src/hcode/btech/mech.ice.c

Go to the documentation of this file.
00001 /*
00002  * Author: Markus Stenberg <fingon@iki.fi>
00003  *
00004  *  Copyright (c) 1997 Markus Stenberg
00005  *  Copyright (c) 1998-2002 Thomas Wouters
00006  *  Copyright (c) 2000-2002 Cord Awtry
00007  *       All rights reserved
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 /* Up -> down */
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 /* Down -> up */
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 /* CHANCE of dropping thru the ice based on 'mech weight */
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 }

Generated on Mon May 28 04:25:22 2007 for BattletechMUX by  doxygen 1.4.7