00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "mech.h"
00011 #include "mech.events.h"
00012 #include "p.mech.update.h"
00013 #include "p.bsuit.h"
00014 #include "p.mech.utils.h"
00015 #include "p.mech.pickup.h"
00016 #include "p.mech.tag.h"
00017
00018 #define TMP_TERR '1'
00019
00020 static void swim_except(MAP * map, MECH * mech, int x, int y, char *msg,
00021 int isbridge)
00022 {
00023 int i, j;
00024 MECH *t;
00025
00026 if(!(Elevation(map, x, y)))
00027 return;
00028 for(i = 0; i < map->first_free; i++) {
00029 j = map->mechsOnMap[i];
00030 if(j < 0)
00031 continue;
00032 t = getMech(j);
00033 if(!t || t == mech)
00034 continue;
00035 if(MechX(t) != x || MechY(t) != y)
00036 continue;
00037 MechTerrain(t) = WATER;
00038 if((!isbridge && (MechZ(t) == 0) && (MechMove(t) != MOVE_HOVER)) ||
00039 (isbridge && MechZ(t) == MechElev(t))) {
00040 MechLOSBroadcast(t, msg);
00041 MechFalls(t, MechElev(t) + isbridge, 0);
00042 if(MechType(t) == CLASS_VEH_GROUND && !Destroyed(t)) {
00043 mech_notify(t, MECHALL,
00044 "Water renders your vehicle inoperable.");
00045 MechLOSBroadcast(t,
00046 "fizzles and pops as water renders it inoperable.");
00047 Destroy(t);
00048 ChannelEmitKill(t, t);
00049 }
00050 }
00051 }
00052 }
00053
00054 static void break_sub(MAP * map, MECH * mech, int x, int y, char *msg)
00055 {
00056 int isbridge = GetRTerrain(map, x, y) == BRIDGE;
00057
00058 SetTerrain(map, x, y, WATER);
00059 if(isbridge)
00060 SetElevation(map, x, y, 1);
00061 swim_except(map, mech, x, y, msg, isbridge);
00062 }
00063
00064
00065 void drop_thru_ice(MECH * mech)
00066 {
00067 MAP *map = FindObjectsData(mech->mapindex);
00068
00069 mech_notify(mech, MECHALL, "You break the ice!");
00070 MechLOSBroadcast(mech, "breaks the ice!");
00071 if(MechMove(mech) != MOVE_FOIL) {
00072 if(MechElev(mech) > 0)
00073 MechLOSBroadcast(mech, "vanishes into the waters!");
00074 }
00075 break_sub(map, mech, MechX(mech), MechY(mech), "goes swimming!");
00076 MechTerrain(mech) = WATER;
00077 if(MechMove(mech) != MOVE_FOIL) {
00078 if(MechElev(mech) > 0)
00079 MechFalls(mech, MechElev(mech), 0);
00080 }
00081 if(MechElev(mech) > 0 && MechType(mech) == CLASS_VEH_GROUND &&
00082 !Destroyed(mech) && !(MechSpecials2(mech) & WATERPROOF_TECH)) {
00083 mech_notify(mech, MECHALL, "Water renders your vehicle inoperable.");
00084 MechLOSBroadcast(mech,
00085 "fizzles and pops as water renders it inoperable.");
00086 Destroy(mech);
00087 ChannelEmitKill(mech, mech);
00088 }
00089 }
00090
00091
00092 void break_thru_ice(MECH * mech)
00093 {
00094 MAP *map = FindObjectsData(mech->mapindex);
00095
00096 MarkForLOSUpdate(mech);
00097 mech_notify(mech, MECHALL, "You break through the ice!");
00098 MechLOSBroadcast(mech, "breaks through the ice!");
00099 break_sub(map, mech, MechX(mech), MechY(mech), "goes swimming!");
00100 MechTerrain(mech) = WATER;
00101 }
00102
00103
00104 int possibly_drop_thru_ice(MECH * mech)
00105 {
00106 if((MechMove(mech) == MOVE_HOVER) || (MechMove(mech) == MOVE_SUB) ||
00107 (MechType(mech) == CLASS_BSUIT))
00108 return 0;
00109 if(Number(1, 6) != 1)
00110 return 0;
00111 drop_thru_ice(mech);
00112 return 1;
00113 }
00114
00115 static int watercount;
00116
00117 static void growable_callback(MAP * map, int x, int y)
00118 {
00119 int terrain = GetRTerrain(map, x, y);
00120 if((IsWater(terrain) && terrain != ICE) ||
00121 GetRTerrain(map, x, y) == TMP_TERR)
00122 watercount++;
00123 }
00124
00125 int growable(MAP * map, int x, int y)
00126 {
00127 watercount = 0;
00128 visit_neighbor_hexes(map, x, y, growable_callback);
00129
00130 if(watercount <= 4 && (watercount < 2 || (Number(1, 6) > watercount)))
00131 return 1;
00132 return 0;
00133 }
00134
00135 static void meltable_callback(MAP * map, int x, int y)
00136 {
00137 if(GetRTerrain(map, x, y) == ICE)
00138 watercount++;
00139 }
00140
00141 int meltable(MAP * map, int x, int y)
00142 {
00143 watercount = 0;
00144 visit_neighbor_hexes(map, x, y, meltable_callback);
00145
00146 if(watercount > 4 && Number(1, 3) > 1)
00147 return 0;
00148 return 1;
00149 }
00150
00151 void ice_growth(dbref player, MAP * map, int num)
00152 {
00153 int x, y;
00154 int count = 0;
00155
00156 for(x = 0; x < map->map_width; x++)
00157 for(y = 0; y < map->map_height; y++)
00158 if(GetRTerrain(map, x, y) == WATER)
00159 if(Number(1, 100) <= num && growable(map, x, y)) {
00160 SetTerrain(map, x, y, TMP_TERR);
00161 count++;
00162 }
00163 for(x = 0; x < map->map_width; x++)
00164 for(y = 0; y < map->map_height; y++)
00165 if(GetRTerrain(map, x, y) == TMP_TERR)
00166 SetTerrain(map, x, y, ICE);
00167 if(count)
00168 notify_printf(player, "%d hexes 'iced'.", count);
00169 else
00170 notify(player, "No hexes 'iced'.");
00171 }
00172
00173 void ice_melt(dbref player, MAP * map, int num)
00174 {
00175 int x, y;
00176 int count = 0;
00177
00178 for(x = 0; x < map->map_width; x++)
00179 for(y = 0; y < map->map_height; y++)
00180 if(GetRTerrain(map, x, y) == ICE)
00181 if(Number(1, 100) <= num && meltable(map, x, y)) {
00182 break_sub(map, NULL, x, y,
00183 "goes swimming as ice breaks!");
00184 SetTerrain(map, x, y, TMP_TERR);
00185 count++;
00186 }
00187 for(x = 0; x < map->map_width; x++)
00188 for(y = 0; y < map->map_height; y++)
00189 if(GetRTerrain(map, x, y) == TMP_TERR)
00190 SetTerrain(map, x, y, WATER);
00191 if(count)
00192 notify_printf(player, "%d hexes melted.", count);
00193 else
00194 notify(player, "No hexes melted.");
00195 }
00196
00197 void map_addice(dbref player, MAP * map, char *buffer)
00198 {
00199 char *args[2];
00200 int num;
00201
00202 DOCHECK(mech_parseattributes(buffer, args, 2) != 1, "Invalid arguments!");
00203 DOCHECK(Readnum(num, args[0]), "Invalid number!");
00204 ice_growth(player, map, num);
00205 }
00206
00207 void map_delice(dbref player, MAP * map, char *buffer)
00208 {
00209 char *args[2];
00210 int num;
00211
00212 DOCHECK(mech_parseattributes(buffer, args, 2) != 1, "Invalid arguments!");
00213 DOCHECK(Readnum(num, args[0]), "Invalid number!");
00214 ice_melt(player, map, num);
00215 }
00216
00217 void possibly_blow_ice(MECH * mech, int weapindx, int x, int y)
00218 {
00219 MAP *map = FindObjectsData(mech->mapindex);
00220
00221 if(GetRTerrain(map, x, y) != ICE)
00222 return;
00223 if(Number(1, 15) > MechWeapons[weapindx].damage)
00224 return;
00225 HexLOSBroadcast(map, x, y, "The ice breaks from the blast!");
00226 break_sub(map, NULL, x, y, "goes swimming as ice breaks!");
00227 }
00228
00229 void possibly_blow_bridge(MECH * mech, int weapindx, int x, int y)
00230 {
00231 MAP *map = FindObjectsData(mech->mapindex);
00232
00233 if(GetRTerrain(map, x, y) != BRIDGE)
00234 return;
00235 if(MapBridgesCS(map))
00236 return;
00237 if(Number(1, 10 * (1 + GetElev(map, x,
00238 y))) > MechWeapons[weapindx].damage) {
00239 HexLOSBroadcast(map, x, y,
00240 "The bridge at $H shudders from direct hit!");
00241 return;
00242 }
00243 HexLOSBroadcast(map, x, y, "The bridge at $H is blown apart!");
00244 break_sub(map, NULL, x, y, "goes swimming as the bridge is blown apart!");
00245 }