119 |
119 |
120 /** Initialize a disaster vehicle. These vehicles are of type VEH_DISASTER, are unclickable |
120 /** Initialize a disaster vehicle. These vehicles are of type VEH_DISASTER, are unclickable |
121 * and owned by nobody */ |
121 * and owned by nobody */ |
122 static void InitializeDisasterVehicle(Vehicle *v, int x, int y, byte z, Direction direction, byte subtype) |
122 static void InitializeDisasterVehicle(Vehicle *v, int x, int y, byte z, Direction direction, byte subtype) |
123 { |
123 { |
124 v = new (v) DisasterVehicle(); |
|
125 v->x_pos = x; |
124 v->x_pos = x; |
126 v->y_pos = y; |
125 v->y_pos = y; |
127 v->z_pos = z; |
126 v->z_pos = z; |
128 v->tile = TileVirtXY(x, y); |
127 v->tile = TileVirtXY(x, y); |
129 v->direction = direction; |
128 v->direction = direction; |
598 AddNewsItem(STR_B004_UFO_LANDS_NEAR, |
597 AddNewsItem(STR_B004_UFO_LANDS_NEAR, |
599 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_ACCIDENT, 0), |
598 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_ACCIDENT, 0), |
600 v->tile, |
599 v->tile, |
601 0); |
600 0); |
602 |
601 |
603 u = ForceAllocateSpecialVehicle(); |
602 u = new DisasterVehicle(); |
604 if (u == NULL) { |
603 if (u == NULL) { |
605 DeleteDisasterVeh(v); |
604 DeleteDisasterVeh(v); |
606 return; |
605 return; |
607 } |
606 } |
608 |
607 |
609 InitializeDisasterVehicle(u, -6 * TILE_SIZE, v->y_pos, 135, DIR_SW, ST_Big_Ufo_Destroyer); |
608 InitializeDisasterVehicle(u, -6 * TILE_SIZE, v->y_pos, 135, DIR_SW, ST_Big_Ufo_Destroyer); |
610 u->u.disaster.unk2 = v->index; |
609 u->u.disaster.big_ufo_destroyer_target = v->index; |
611 |
610 |
612 w = ForceAllocateSpecialVehicle(); |
611 w = new DisasterVehicle(); |
613 if (w == NULL) return; |
612 if (w == NULL) return; |
614 |
613 |
615 u->next = w; |
614 u->next = w; |
616 InitializeDisasterVehicle(w, -6 * TILE_SIZE, v->y_pos, 0, DIR_SW, ST_Big_Ufo_Destroyer_Shadow); |
615 InitializeDisasterVehicle(w, -6 * TILE_SIZE, v->y_pos, 0, DIR_SW, ST_Big_Ufo_Destroyer_Shadow); |
617 w->vehstatus |= VS_SHADOW; |
616 w->vehstatus |= VS_SHADOW; |
665 DeleteDisasterVeh(v); |
664 DeleteDisasterVeh(v); |
666 return; |
665 return; |
667 } |
666 } |
668 |
667 |
669 if (v->current_order.dest == 0) { |
668 if (v->current_order.dest == 0) { |
670 u = GetVehicle(v->u.disaster.unk2); |
669 u = GetVehicle(v->u.disaster.big_ufo_destroyer_target); |
671 if (delta(v->x_pos, u->x_pos) > TILE_SIZE) return; |
670 if (delta(v->x_pos, u->x_pos) > TILE_SIZE) return; |
672 v->current_order.dest = 1; |
671 v->current_order.dest = 1; |
673 |
672 |
674 CreateEffectVehicleRel(u, 0, 7, 8, EV_EXPLOSION_LARGE); |
673 CreateEffectVehicleRel(u, 0, 7, 8, EV_EXPLOSION_LARGE); |
675 SndPlayVehicleFx(SND_12_EXPLOSION, u); |
674 SndPlayVehicleFx(SND_12_EXPLOSION, u); |
758 |
757 |
759 /** Zeppeliner which crashes on a small airport if one found, |
758 /** Zeppeliner which crashes on a small airport if one found, |
760 * otherwise crashes on a random tile */ |
759 * otherwise crashes on a random tile */ |
761 static void Disaster_Zeppeliner_Init() |
760 static void Disaster_Zeppeliner_Init() |
762 { |
761 { |
763 Vehicle *v = ForceAllocateSpecialVehicle(), *u; |
762 Vehicle *v = new DisasterVehicle(), *u; |
764 Station *st; |
763 Station *st; |
765 int x; |
764 int x; |
766 |
765 |
767 if (v == NULL) return; |
766 if (v == NULL) return; |
768 |
767 |
779 } |
778 } |
780 |
779 |
781 InitializeDisasterVehicle(v, x, 0, 135, DIR_SE, ST_Zeppeliner); |
780 InitializeDisasterVehicle(v, x, 0, 135, DIR_SE, ST_Zeppeliner); |
782 |
781 |
783 /* Allocate shadow too? */ |
782 /* Allocate shadow too? */ |
784 u = ForceAllocateSpecialVehicle(); |
783 u = new DisasterVehicle(); |
785 if (u != NULL) { |
784 if (u != NULL) { |
786 v->next = u; |
785 v->next = u; |
787 InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Zeppeliner_Shadow); |
786 InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Zeppeliner_Shadow); |
788 u->vehstatus |= VS_SHADOW; |
787 u->vehstatus |= VS_SHADOW; |
789 } |
788 } |
792 |
791 |
793 /** Ufo which flies around aimlessly from the middle of the map a bit |
792 /** Ufo which flies around aimlessly from the middle of the map a bit |
794 * until it locates a road vehicle which it targets and then destroys */ |
793 * until it locates a road vehicle which it targets and then destroys */ |
795 static void Disaster_Small_Ufo_Init() |
794 static void Disaster_Small_Ufo_Init() |
796 { |
795 { |
797 Vehicle *v = ForceAllocateSpecialVehicle(), *u; |
796 Vehicle *v = new DisasterVehicle(), *u; |
798 int x; |
797 int x; |
799 |
798 |
800 if (v == NULL) return; |
799 if (v == NULL) return; |
801 |
800 |
802 x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; |
801 x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; |
804 InitializeDisasterVehicle(v, x, 0, 135, DIR_SE, ST_Small_Ufo); |
803 InitializeDisasterVehicle(v, x, 0, 135, DIR_SE, ST_Small_Ufo); |
805 v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2); |
804 v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2); |
806 v->age = 0; |
805 v->age = 0; |
807 |
806 |
808 /* Allocate shadow too? */ |
807 /* Allocate shadow too? */ |
809 u = ForceAllocateSpecialVehicle(); |
808 u = new DisasterVehicle(); |
810 if (u != NULL) { |
809 if (u != NULL) { |
811 v->next = u; |
810 v->next = u; |
812 InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Small_Ufo_Shadow); |
811 InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Small_Ufo_Shadow); |
813 u->vehstatus |= VS_SHADOW; |
812 u->vehstatus |= VS_SHADOW; |
814 } |
813 } |
831 } |
830 } |
832 } |
831 } |
833 |
832 |
834 if (found == NULL) return; |
833 if (found == NULL) return; |
835 |
834 |
836 v = ForceAllocateSpecialVehicle(); |
835 v = new DisasterVehicle(); |
837 if (v == NULL) return; |
836 if (v == NULL) return; |
838 |
837 |
839 /* Start from the bottom (south side) of the map */ |
838 /* Start from the bottom (south side) of the map */ |
840 x = (MapSizeX() + 9) * TILE_SIZE - 1; |
839 x = (MapSizeX() + 9) * TILE_SIZE - 1; |
841 y = TileY(found->xy) * TILE_SIZE + 37; |
840 y = TileY(found->xy) * TILE_SIZE + 37; |
842 |
841 |
843 InitializeDisasterVehicle(v, x, y, 135, DIR_NE, ST_Airplane); |
842 InitializeDisasterVehicle(v, x, y, 135, DIR_NE, ST_Airplane); |
844 |
843 |
845 u = ForceAllocateSpecialVehicle(); |
844 u = new DisasterVehicle(); |
846 if (u != NULL) { |
845 if (u != NULL) { |
847 v->next = u; |
846 v->next = u; |
848 InitializeDisasterVehicle(u, x, y, 0, DIR_SE, ST_Airplane_Shadow); |
847 InitializeDisasterVehicle(u, x, y, 0, DIR_SE, ST_Airplane_Shadow); |
849 u->vehstatus |= VS_SHADOW; |
848 u->vehstatus |= VS_SHADOW; |
850 } |
849 } |
867 } |
866 } |
868 } |
867 } |
869 |
868 |
870 if (found == NULL) return; |
869 if (found == NULL) return; |
871 |
870 |
872 v = ForceAllocateSpecialVehicle(); |
871 v = new DisasterVehicle(); |
873 if (v == NULL) return; |
872 if (v == NULL) return; |
874 |
873 |
875 x = -16 * TILE_SIZE; |
874 x = -16 * TILE_SIZE; |
876 y = TileY(found->xy) * TILE_SIZE + 37; |
875 y = TileY(found->xy) * TILE_SIZE + 37; |
877 |
876 |
878 InitializeDisasterVehicle(v, x, y, 135, DIR_SW, ST_Helicopter); |
877 InitializeDisasterVehicle(v, x, y, 135, DIR_SW, ST_Helicopter); |
879 |
878 |
880 u = ForceAllocateSpecialVehicle(); |
879 u = new DisasterVehicle(); |
881 if (u != NULL) { |
880 if (u != NULL) { |
882 v->next = u; |
881 v->next = u; |
883 InitializeDisasterVehicle(u, x, y, 0, DIR_SW, ST_Helicopter_Shadow); |
882 InitializeDisasterVehicle(u, x, y, 0, DIR_SW, ST_Helicopter_Shadow); |
884 u->vehstatus |= VS_SHADOW; |
883 u->vehstatus |= VS_SHADOW; |
885 |
884 |
886 w = ForceAllocateSpecialVehicle(); |
885 w = new DisasterVehicle(); |
887 if (w != NULL) { |
886 if (w != NULL) { |
888 u->next = w; |
887 u->next = w; |
889 InitializeDisasterVehicle(w, x, y, 140, DIR_SW, ST_Helicopter_Rotors); |
888 InitializeDisasterVehicle(w, x, y, 140, DIR_SW, ST_Helicopter_Rotors); |
890 } |
889 } |
891 } |
890 } |
894 |
893 |
895 /* Big Ufo which lands on a piece of rail and will consequently be shot |
894 /* Big Ufo which lands on a piece of rail and will consequently be shot |
896 * down by a combat airplane, destroying the surroundings */ |
895 * down by a combat airplane, destroying the surroundings */ |
897 static void Disaster_Big_Ufo_Init() |
896 static void Disaster_Big_Ufo_Init() |
898 { |
897 { |
899 Vehicle *v = ForceAllocateSpecialVehicle(), *u; |
898 Vehicle *v = new DisasterVehicle(), *u; |
900 int x, y; |
899 int x, y; |
901 |
900 |
902 if (v == NULL) return; |
901 if (v == NULL) return; |
903 |
902 |
904 x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; |
903 x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; |
907 InitializeDisasterVehicle(v, x, y, 135, DIR_NW, ST_Big_Ufo); |
906 InitializeDisasterVehicle(v, x, y, 135, DIR_NW, ST_Big_Ufo); |
908 v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2); |
907 v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2); |
909 v->age = 0; |
908 v->age = 0; |
910 |
909 |
911 /* Allocate shadow too? */ |
910 /* Allocate shadow too? */ |
912 u = ForceAllocateSpecialVehicle(); |
911 u = new DisasterVehicle(); |
913 if (u != NULL) { |
912 if (u != NULL) { |
914 v->next = u; |
913 v->next = u; |
915 InitializeDisasterVehicle(u, x, y, 0, DIR_NW, ST_Big_Ufo_Shadow); |
914 InitializeDisasterVehicle(u, x, y, 0, DIR_NW, ST_Big_Ufo_Shadow); |
916 u->vehstatus |= VS_SHADOW; |
915 u->vehstatus |= VS_SHADOW; |
917 } |
916 } |
984 AddNewsItem(STR_B005_COAL_MINE_SUBSIDENCE_LEAVES, |
983 AddNewsItem(STR_B005_COAL_MINE_SUBSIDENCE_LEAVES, |
985 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_ACCIDENT, 0), i->xy + TileDiffXY(1, 1), 0); |
984 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_ACCIDENT, 0), i->xy + TileDiffXY(1, 1), 0); |
986 |
985 |
987 { |
986 { |
988 TileIndex tile = i->xy; |
987 TileIndex tile = i->xy; |
989 TileIndexDiff step = TileOffsByDiagDir(GB(Random(), 0, 2)); |
988 TileIndexDiff step = TileOffsByDiagDir((DiagDirection)GB(Random(), 0, 2)); |
990 uint n; |
989 uint n; |
991 |
990 |
992 for (n = 0; n < 30; n++) { |
991 for (n = 0; n < 30; n++) { |
993 DisasterClearSquare(tile); |
992 DisasterClearSquare(tile); |
994 tile = TILE_MASK(tile + step); |
993 tile = TILE_MASK(tile + step); |