src/hcode/btech/template.c

Go to the documentation of this file.
00001 /*
00002  *  Copyright (c) 1999-2005 Kevin Stevens
00003  *      All rights reserved
00004  */
00005 
00006 /* 
00007    Code to read and write mech and vehicle templates
00008    Created by Nim 9/16/96
00009 
00010    $Id: template.c,v 1.9 2005/08/10 14:09:34 av1-op Exp $
00011    Last modified: Fri Sep 18 13:02:31 1998 fingon
00012  */
00013 
00014 /* 01/21/02 Added many commods <KM> */
00015 
00016 /* 09/16/96 Some touches by Markus Stenberg <fingon@iki.fi> */
00017 
00018 /* 09/16/96 Some?? ... ya right ;-) (nim)                  */
00019 
00020 /* 09/17/96 Ok, ton of touches then :-P (Mark) */
00021 
00022 #include "config.h"
00023 
00024 #define MAX_STRING_LENGTH 8192
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <ctype.h>
00029 
00030 #include "mech.h"
00031 #include "create.h"
00032 #include "mech.events.h"
00033 #include "coolmenu.h"
00034 #include "failures.h"
00035 #include "aero.bomb.h"
00036 #include "mech.partnames.h"
00037 #include "p.mech.utils.h"
00038 #include "p.mech.partnames.h"
00039 #include "p.mech.consistency.h"
00040 #include "p.map.conditions.h"
00041 #include "p.aero.bomb.h"
00042 #include "p.mech.mechref_ident.h"
00043 #include "p.crit.h"
00044 #include "p.bsuit.h"
00045 #include "p.mech.c3.h"
00046 
00047 #define MODE_UNKNOWN 0
00048 #define MODE_NORMAL 1
00049 
00050 char *load_cmds[] = {
00051         "Reference", "Type", "Move_Type", "Tons", "Tac_Range",
00052         "LRS_Range", "Radio_Range", "Scan_Range", "Heat_Sinks",
00053         "Max_Speed", "Specials", "Armor", "Internals", "Rear",
00054         "Config", "Computer", "Name", "Jump_Speed", "Radio",
00055         "SI", "Fuel", "Comment", "RadioType",
00056         "Mech_BV", "Cargo_Space", "Max_Suits", "InfantrySpecials",
00057         "Max_Ton",
00058         NULL
00059 };
00060 
00061 char *internals[] = {
00062         "ShoulderOrHip",
00063         "UpperActuator",
00064         "LowerActuator",
00065         "HandOrFootActuator",
00066         "LifeSupport",
00067         "Sensors",
00068         "Cockpit",
00069         "Engine",
00070         "Gyro",
00071         "HeatSink",
00072         "JumpJet",
00073         "Case",
00074         "FerroFibrous",
00075         "EndoSteel",
00076         "TripleStrengthMyomer",
00077         "TargetingComputer",
00078         "Masc",
00079         "C3Master",
00080         "C3Slave",
00081         "BeagleProbe",
00082         "ArtemisIV",
00083         "Ecm",
00084         "Axe",
00085         "Sword",
00086         "Mace",
00087         "Claw",
00088         "DSAeroDoor",
00089         "DSMechDoor",
00090         "Fuel_Tank",
00091         "TAG",
00092         "DSVehicleDoor",
00093         "DSCargoDoor",
00094         "LAM_Equipment",
00095         "CaseII",
00096         "StealthArmor",
00097         "NullSig_Device",
00098         "C3i",
00099         "AngelEcm",
00100         "HvyFerroFibrous",
00101         "LtFerroFibrous",
00102         "BloodhoundProbe",
00103         "PurifierArmor",
00104         "KageStealthUnit",
00105         "AchileusStealthUnit",
00106         "InfiltratorStealthUnit",
00107         "InfiltratorIIStealthUnit",
00108         "SuperCharger",
00109         "Dual_Saw",
00110         NULL
00111 };
00112 
00113 #ifdef BT_PART_WEIGHTS
00114 int internalsweight[] = {
00115         102,                                            /* ShoulderOrHip */
00116         102,                                            /* UpperActuator */
00117         102,                                            /* LowerActuator */
00118         102,                                            /* HandOrFootActuator */
00119         204,                                            /* LifeSupport */
00120         102,                                            /* Sensors */
00121         512,                                            /* Cockpit */
00122         1024,                                           /* Engine */
00123         512,                                            /* Gyro */
00124         204,                                            /* HeatSink */
00125         204,                                            /* JumpJet */
00126         51,                                                     /* Case */
00127         153,                                            /* FerroFibrous */
00128         153,                                            /* EndoSteel */
00129         51,                                                     /* TripleStrengthMyomer */
00130         204,                                            /* TargetingComputer */
00131         51,                                                     /* Masc */
00132         512,                                            /* C3Master */
00133         102,                                            /* C3Slave */
00134         102,                                            /* BeagleProbe */
00135         153,                                            /* ArtemisIV */
00136         204,                                            /* Ecm */
00137         51,                                                     /* Axe */
00138         25,                                                     /* Sword */
00139         102,                                            /* Mace */
00140         75,                                                     /* Claw */
00141         1024,                                           /* DSAeroDoor */
00142         1024,                                           /* DSMechDoor */
00143         102,                                            /* Fuel_Tank */
00144         51,                                                     /* TAG */
00145         1024,                                           /* DSVehicleDoor */
00146         1024,                                           /* DSCargoDoor */
00147         306,                                            /* LAM_Equipment */
00148         306,                                            /* CaseII */
00149         3,                                                      /* StealthArmor */
00150         1024,                                           /* NullSig_Device */
00151         512,                                            /* C3i */
00152         204,                                            /* AngelECM */
00153         7,                                                      /* HvyFerroFibrous */
00154         1,                                                      /* LtFerroFibrous */
00155         102,                                            /* BloodhoundProbe */
00156         2,                                                      /* PurifierArmor */
00157         102,                                            /* KageStealthUnit */
00158         102,                                            /* AchileusStealthUnit */
00159         102,                                            /* InfiltratorStealthUnit */
00160         102,                                            /* InfiltratorIIStealthUnit */
00161         1024,                                           /* Dual_Saw */
00162 };
00163 #endif /* BT_PART_WEIGHTS */
00164 
00165 char *cargo[] = {
00166         "Ammo_LBX2",
00167         "Ammo_LBX5_LBX",
00168         "Ammo_LBX10_LBX",
00169         "Ammo_LBX20_LBX",
00170         "Ammo_LRM",
00171         "Ammo_SRM",
00172         "Ammo_SSRM",
00173         "Ammo_LRM_NARC",
00174         "Ammo_SRM_NARC",
00175         "Ammo_SSRM_NARC",
00176         "Ammo_LRM_Artemis",
00177         "Ammo_SRM_Artemis",
00178         "Ammo_SSRM_Artemis",
00179         "Petroleum",
00180         "Phosphorus",
00181         "Hydrogen",
00182         "Gold",
00183         "Natural_Extracts",
00184         "Marijuana",
00185         "Sulfur",
00186         "Sodium",
00187         "Plutonium",
00188         "Ore",
00189         "Steel",
00190         "Plastics",
00191         "Medical_Supplies",
00192         "Computers",
00193         "Explosives",
00194         "ES_Internal",
00195         "FF_Armor",
00196         "XL_Engine",
00197         "Double_HeatSink",
00198         "ICE_Engine",
00199         "Electric",
00200         "Internal",
00201         "Armor",
00202         "Actuator",
00203         "Aero_Fuel",
00204         "DS_Fuel",
00205         "VTOL_Fuel",
00206         "Ammo_LRM_Swarm",
00207         "Ammo_LRM_Swarm1",
00208         "Ammo_SRM_Inferno",
00209         "XXL_Engine",
00210         "Compact_Engine",
00211         "HD_Armor",
00212         "RE_Internals",
00213         "CO_Internals",
00214         "Ammo_MRM",
00215         "Light_Engine",
00216         "CaseII",
00217         "STH_Armor",
00218         "NullSigSys",
00219         "Silicon",
00220         "HVY_FF_Armor",
00221         "LT_FF_Armor",
00222         "Ammo_iNARC_Explosive",
00223         "Ammo_iNARC_Haywire",
00224         "Ammo_iNARC_ECM",
00225         "Ammo_iNARC_Nemesis",
00226         "Ammo_AC2_Pierce",
00227         "Ammo_AC5_Pierce",
00228         "Ammo_AC10_Pierce",
00229         "Ammo_AC20_Pierce",
00230         "Ammo_LAC2_Pierce",
00231         "Ammo_LAC5_Pierce",
00232         "Ammo_AC2_Flechette",
00233         "Ammo_AC5_Flechette",
00234         "Ammo_AC10_Flechette",
00235         "Ammo_AC20_Flechette",
00236         "Ammo_LAC2_Flechette",
00237         "Ammo_LAC5_Flechette",
00238         "Ammo_AC2_Incendiary",
00239         "Ammo_AC5_Incendiary",
00240         "Ammo_AC10_Incendiary",
00241         "Ammo_AC20_Incendiary",
00242         "Ammo_LAC2_Incendiary",
00243         "Ammo_LAC5_Incendiary",
00244         "Ammo_AC2_Precision",
00245         "Ammo_AC5_Precision",
00246         "Ammo_AC10_Precision",
00247         "Ammo_AC20_Precision",
00248         "Ammo_LAC2_Precision",
00249         "Ammo_LAC5_Precision",
00250         "Ammo_LR_DFM",
00251         "Ammo_SR_DFM",
00252         "Ammo_SLRM",
00253         "Ammo_ELRM",
00254         "BSuit_Sensor",
00255         "BSuit_LifeSupport",
00256         "BSuit_Electronic",
00257         "Oil",
00258         "Water",
00259         "Earth",
00260         "Oxygen",
00261         "Nitrogen",
00262         "Nickel",
00263         "Steel",
00264         "Iron",
00265         "Brass",
00266         "Platinum",
00267         "Copper",
00268         "Aluminum",
00269         "Consumer_Good",
00270         "Machinery",
00271         "Slaves",
00272         "Timbiqui_Dark",
00273         "Cocaine",
00274         "Heroine",
00275         "Marble",
00276         "Glass",
00277         "Diamond",
00278         "Coal",
00279         "Food",
00280         "Zinc",
00281         "Fabric",
00282         "Clothing",
00283         "Wood",
00284         "Pulp",
00285         "Lumber",
00286         "Rubber",
00287         "Seeds",
00288         "Fertilizer",
00289         "Salt",
00290         "Lithium",
00291         "Helium",
00292         "Larium",
00293         "Uranium",
00294         "Iridium",
00295         "Titanium",
00296         "Concrete",
00297         "FerroCrete",
00298         "Building_Supplies",
00299         "Kevlar",
00300         "Waste",
00301         "Livestock",
00302         "Paper",
00303         "XL_Gyro",
00304         "HeavyDuty_Gyro",
00305         "Compact_Gyro",
00306         "Compact_HeatSink",
00307         "SearchLight",
00308 #ifdef BT_COMPLEXREPAIRS
00309         "Sensors_10",
00310         "Sensors_20",
00311         "Sensors_30",
00312         "Sensors_40",
00313         "Sensors_50",
00314         "Sensors_60",
00315         "Sensors_70",
00316         "Sensors_80",
00317         "Sensors_90",
00318         "Sensors_100",
00319         "Myomer_10",
00320         "Myomer_20",
00321         "Myomer_30",
00322         "Myomer_40",
00323         "Myomer_50",
00324         "Myomer_60",
00325         "Myomer_70",
00326         "Myomer_80",
00327         "Myomer_90",
00328         "Myomer_100",
00329         "TripleMyomer_10",
00330         "TripleMyomer_20",
00331         "TripleMyomer_30",
00332         "TripleMyomer_40",
00333         "TripleMyomer_50",
00334         "TripleMyomer_60",
00335         "TripleMyomer_70",
00336         "TripleMyomer_80",
00337         "TripleMyomer_90",
00338         "TripleMyomer_100",
00339         "Internal_10",
00340         "Internal_20",
00341         "Internal_30",
00342         "Internal_40",
00343         "Internal_50",
00344         "Internal_60",
00345         "Internal_70",
00346         "Internal_80",
00347         "Internal_90",
00348         "Internal_100",
00349         "ES_Internal_10",
00350         "ES_Internal_20",
00351         "ES_Internal_30",
00352         "ES_Internal_40",
00353         "ES_Internal_50",
00354         "ES_Internal_60",
00355         "ES_Internal_70",
00356         "ES_Internal_80",
00357         "ES_Internal_90",
00358         "ES_Internal_100",
00359         "JumpJet_10",
00360         "JumpJet_20",
00361         "JumpJet_30",
00362         "JumpJet_40",
00363         "JumpJet_50",
00364         "JumpJet_60",
00365         "JumpJet_70",
00366         "JumpJet_80",
00367         "JumpJet_90",
00368         "JumpJet_100",
00369         "UpperArmActuator_10",
00370         "UpperArmActuator_20",
00371         "UpperArmActuator_30",
00372         "UpperArmActuator_40",
00373         "UpperArmActuator_50",
00374         "UpperArmActuator_60",
00375         "UpperArmActuator_70",
00376         "UpperArmActuator_80",
00377         "UpperArmActuator_90",
00378         "UpperArmActuator_100",
00379         "LowerArmActuator_10",
00380         "LowerArmActuator_20",
00381         "LowerArmActuator_30",
00382         "LowerArmActuator_40",
00383         "LowerArmActuator_50",
00384         "LowerArmActuator_60",
00385         "LowerArmActuator_70",
00386         "LowerArmActuator_80",
00387         "LowerArmActuator_90",
00388         "LowerArmActuator_100",
00389         "HandActuator_10",
00390         "HandActuator_20",
00391         "HandActuator_30",
00392         "HandActuator_40",
00393         "HandActuator_50",
00394         "HandActuator_60",
00395         "HandActuator_70",
00396         "HandActuator_80",
00397         "HandActuator_90",
00398         "HandActuator_100",
00399         "UpperLegActuator_10",
00400         "UpperLegActuator_20",
00401         "UpperLegActuator_30",
00402         "UpperLegActuator_40",
00403         "UpperLegActuator_50",
00404         "UpperLegActuator_60",
00405         "UpperLegActuator_70",
00406         "UpperLegActuator_80",
00407         "UpperLegActuator_90",
00408         "UpperLegActuator_100",
00409         "LowerLegActuator_10",
00410         "LowerLegActuator_20",
00411         "LowerLegActuator_30",
00412         "LowerLegActuator_40",
00413         "LowerLegActuator_50",
00414         "LowerLegActuator_60",
00415         "LowerLegActuator_70",
00416         "LowerLegActuator_80",
00417         "LowerLegActuator_90",
00418         "LowerLegActuator_100",
00419         "FootActuator_10",
00420         "FootActuator_20",
00421         "FootActuator_30",
00422         "FootActuator_40",
00423         "FootActuator_50",
00424         "FootActuator_60",
00425         "FootActuator_70",
00426         "FootActuator_80",
00427         "FootActuator_90",
00428         "FootActuator_100",
00429         "Engine_20",
00430         "Engine_40",
00431         "Engine_60",
00432         "Engine_80",
00433         "Engine_100",
00434         "Engine_120",
00435         "Engine_140",
00436         "Engine_160",
00437         "Engine_180",
00438         "Engine_200",
00439         "Engine_220",
00440         "Engine_240",
00441         "Engine_260",
00442         "Engine_280",
00443         "Engine_300",
00444         "Engine_320",
00445         "Engine_340",
00446         "Engine_360",
00447         "Engine_380",
00448         "Engine_400",
00449         "XL_Engine_20",
00450         "XL_Engine_40",
00451         "XL_Engine_60",
00452         "XL_Engine_80",
00453         "XL_Engine_100",
00454         "XL_Engine_120",
00455         "XL_Engine_140",
00456         "XL_Engine_160",
00457         "XL_Engine_180",
00458         "XL_Engine_200",
00459         "XL_Engine_220",
00460         "XL_Engine_240",
00461         "XL_Engine_260",
00462         "XL_Engine_280",
00463         "XL_Engine_300",
00464         "XL_Engine_320",
00465         "XL_Engine_340",
00466         "XL_Engine_360",
00467         "XL_Engine_380",
00468         "XL_Engine_400",
00469         "ICE_Engine_20",
00470         "ICE_Engine_40",
00471         "ICE_Engine_60",
00472         "ICE_Engine_80",
00473         "ICE_Engine_100",
00474         "ICE_Engine_120",
00475         "ICE_Engine_140",
00476         "ICE_Engine_160",
00477         "ICE_Engine_180",
00478         "ICE_Engine_200",
00479         "ICE_Engine_220",
00480         "ICE_Engine_240",
00481         "ICE_Engine_260",
00482         "ICE_Engine_280",
00483         "ICE_Engine_300",
00484         "ICE_Engine_320",
00485         "ICE_Engine_340",
00486         "ICE_Engine_360",
00487         "ICE_Engine_380",
00488         "ICE_Engine_400",
00489         "Light_Engine_20",
00490         "Light_Engine_40",
00491         "Light_Engine_60",
00492         "Light_Engine_80",
00493         "Light_Engine_100",
00494         "Light_Engine_120",
00495         "Light_Engine_140",
00496         "Light_Engine_160",
00497         "Light_Engine_180",
00498         "Light_Engine_200",
00499         "Light_Engine_220",
00500         "Light_Engine_240",
00501         "Light_Engine_260",
00502         "Light_Engine_280",
00503         "Light_Engine_300",
00504         "Light_Engine_320",
00505         "Light_Engine_340",
00506         "Light_Engine_360",
00507         "Light_Engine_380",
00508         "Light_Engine_400",
00509         "CO_Internal_10",
00510         "CO_Internal_20",
00511         "CO_Internal_30",
00512         "CO_Internal_40",
00513         "CO_Internal_50",
00514         "CO_Internal_60",
00515         "CO_Internal_70",
00516         "CO_Internal_80",
00517         "CO_Internal_90",
00518         "CO_Internal_100",
00519         "RE_Internal_10",
00520         "RE_Internal_20",
00521         "RE_Internal_30",
00522         "RE_Internal_40",
00523         "RE_Internal_50",
00524         "RE_Internal_60",
00525         "RE_Internal_70",
00526         "RE_Internal_80",
00527         "RE_Internal_90",
00528         "RE_Internal_100",
00529         "Gyro_1",
00530         "Gyro_2",
00531         "Gyro_3",
00532         "Gyro_4",
00533         "XL_Gyro_1",
00534         "XL_Gyro_2",
00535         "XL_Gyro_3",
00536         "XL_Gyro_4",
00537         "HD_Gyro_1",
00538         "HD_Gyro_2",
00539         "HD_Gyro_3",
00540         "HD_Gyro_4",
00541         "Compact_Gyro_1",
00542         "Compact_Gyro_2",
00543         "Compact_Gyro_3",
00544         "Compact_Gyro_4",
00545         "XXL_Engine_20",
00546         "XXL_Engine_40",
00547         "XXL_Engine_60",
00548         "XXL_Engine_80",
00549         "XXL_Engine_100",
00550         "XXL_Engine_120",
00551         "XXL_Engine_140",
00552         "XXL_Engine_160",
00553         "XXL_Engine_180",
00554         "XXL_Engine_200",
00555         "XXL_Engine_220",
00556         "XXL_Engine_240",
00557         "XXL_Engine_260",
00558         "XXL_Engine_280",
00559         "XXL_Engine_300",
00560         "XXL_Engine_320",
00561         "XXL_Engine_340",
00562         "XXL_Engine_360",
00563         "XXL_Engine_380",
00564         "XXL_Engine_400",
00565         "Compact_Engine_20",
00566         "Compact_Engine_40",
00567         "Compact_Engine_60",
00568         "Compact_Engine_80",
00569         "Compact_Engine_100",
00570         "Compact_Engine_120",
00571         "Compact_Engine_140",
00572         "Compact_Engine_160",
00573         "Compact_Engine_180",
00574         "Compact_Engine_200",
00575         "Compact_Engine_220",
00576         "Compact_Engine_240",
00577         "Compact_Engine_260",
00578         "Compact_Engine_280",
00579         "Compact_Engine_300",
00580         "Compact_Engine_320",
00581         "Compact_Engine_340",
00582         "Compact_Engine_360",
00583         "Compact_Engine_380",
00584         "Compact_Engine_400",
00585 #endif
00586         NULL
00587 };
00588 
00589 #ifdef BT_PART_WEIGHTS
00590 int cargoweight[] = {
00591         1024,                                           /* Ammo_LBX2 */
00592         1024,                                           /* Ammo_LBX5_LBX */
00593         1024,                                           /* Ammo_LBX10_LBX */
00594         1024,                                           /* Ammo_LBX20_LBX */
00595         1024,                                           /* Ammo_LRM */
00596         1024,                                           /* Ammo_SRM */
00597         1024,                                           /* Ammo_SSRM */
00598         1024,                                           /* Ammo_LRM_NARC */
00599         1024,                                           /* Ammo_SRM_NARC */
00600         1024,                                           /* Ammo_SSRM_NARC */
00601         1024,                                           /* Ammo_LRM_Artemis */
00602         1024,                                           /* Ammo_SRM_Artemis */
00603         1024,                                           /* Ammo_SSRM_Artemis */
00604         102,                                            /* Petroleum */
00605         102,                                            /* Phosphorus */
00606         102,                                            /* Hydrogen */
00607         204,                                            /* Gold */
00608         51,                                                     /* Natural_Extracts */
00609         10,                                                     /* Marijuana */
00610         10,                                                     /* Sulfur */
00611         10,                                                     /* Sodium */
00612         306,                                            /* Plutonium */
00613         51,                                                     /* Ore */
00614         204,                                            /* Steel */
00615         51,                                                     /* Plastics */
00616         8,                                                      /* Medical_Supplies */
00617         306,                                            /* Computers */
00618         204,                                            /* Explosives */
00619         5,                                                      /* ES_Internal */
00620         2,                                                      /* FF_Armor */
00621         512,                                            /* XL_Engine */
00622         342,                                            /* Double_Heatsink */
00623         512,                                            /* ICE_Engine */
00624         51,                                                     /* Electric */
00625         5,                                                      /* Internal */
00626         3,                                                      /* Armor */
00627         102,                                            /* Actuator */
00628         10,                                                     /* Aero_Fuel */
00629         20,                                                     /* DS_Fuel */
00630         2,                                                      /* VTOL_Fuel */
00631         1024,                                           /* Ammo_LRM_Swarm */
00632         1024,                                           /* Ammo_LRM_Swarm1 */
00633         1024,                                           /* Ammo_SRM_Inferno */
00634         1024,                                           /* XXL_Engine */
00635         2048,                                           /* Compact_Engine */
00636         6,                                                      /* HD_Armor */
00637         4,                                                      /* RE_Internals */
00638         2,                                                      /* CO_Internals */
00639         1024,                                           /* Ammo_MRM */
00640         512,                                            /* Light_Engine */
00641         62,                                                     /* CaseII */
00642         3,                                                      /* STH_Armor */
00643         1024,                                           /* NullSigSys */
00644         80,                                                     /* Silicon */
00645         7,                                                      /* HVY_FF_Armor */
00646         1,                                                      /* LT_FF_Armor */
00647         1024,                                           /* Ammo_iNARC_Explosive */
00648         1024,                                           /* Ammo_iNARC_Haywire */
00649         1024,                                           /* Ammo_iNARC_ECM */
00650         1024,                                           /* Ammo_iNARC_Nemesis */
00651         1024,                                           /* Ammo_AC2_AP */
00652         1024,                                           /* Ammo_AC5_AP */
00653         1024,                                           /* Ammo_AC10_AP */
00654         1024,                                           /* Ammo_AC20_AP */
00655         1024,                                           /* Ammo_LAC2_AP */
00656         1024,                                           /* Ammo_LAC5_AP */
00657         1024,                                           /* Ammo_AC2_Flechette */
00658         1024,                                           /* Ammo_AC5_Flechette */
00659         1024,                                           /* Ammo_AC10_Flechette */
00660         1024,                                           /* Ammo_AC20_Flechette */
00661         1024,                                           /* Ammo_LAC2_Flechette */
00662         1024,                                           /* Ammo_LAC5_Flechette */
00663         1024,                                           /* Ammo_AC2_Incendiary */
00664         1024,                                           /* Ammo_AC5_Incendiary */
00665         1024,                                           /* Ammo_AC10_Incendiary */
00666         1024,                                           /* Ammo_AC20_Incendiary */
00667         1024,                                           /* Ammo_LAC2_Incendiary */
00668         1024,                                           /* Ammo_LAC5_Incendiary */
00669         1024,                                           /* Ammo_AC2_Precision */
00670         1024,                                           /* Ammo_AC5_Precision */
00671         1024,                                           /* Ammo_AC10_Precision */
00672         1024,                                           /* Ammo_AC20_Precision */
00673         1024,                                           /* Ammo_LAC2_Precision */
00674         1024,                                           /* Ammo_LAC5_Precision */
00675         1024,                                           /* Ammo_LR_DFM */
00676         1024,                                           /* Ammo_SR_DFM */
00677         1024,                                           /* Ammo_SLRM */
00678         1024,                                           /* Ammo_ELRM */
00679         102,                                            /* BSuit_Sensor */
00680         61,                                                     /* BSuit_LifeSupport */
00681         10,                                                     /* BSuit_Electronic */
00682         306,                                            /* Oil */
00683         102,                                            /* Water */
00684         204,                                            /* Earth */
00685         21,                                                     /* Oxygen */
00686         102,                                            /* Nitrogen */
00687         102,                                            /* Nickel */
00688         204,                                            /* Steel */
00689         204,                                            /* Iron */
00690         204,                                            /* Brass */
00691         204,                                            /* Platinum */
00692         204,                                            /* Copper */
00693         204,                                            /* Aluminum */
00694         61,                                                     /* Consumer_Good */
00695         312,                                            /* Machinery */
00696         102,                                            /* Slaves */
00697         21,                                                     /* Timbiqui_Dark */
00698         10,                                                     /* Cocaine */
00699         10,                                                     /* Heroine */
00700         424,                                            /* Marble */
00701         408,                                            /* Glass */
00702         204,                                            /* Diamond */
00703         306,                                            /* Coal */
00704         204,                                            /* Food */
00705         102,                                            /* Zinc */
00706         204,                                            /* Fabric */
00707         204,                                            /* Clothing */
00708         408,                                            /* Wood */
00709         204,                                            /* Pulp */
00710         520,                                            /* Lumber */
00711         204,                                            /* Rubber */
00712         102,                                            /* Seeds */
00713         102,                                            /* Fertilizer */
00714         102,                                            /* Salt */
00715         204,                                            /* Lithium */
00716         102,                                            /* Helium */
00717         306,                                            /* Larium */
00718         306,                                            /* Uranium */
00719         306,                                            /* Iridium */
00720         408,                                            /* Titanium */
00721         306,                                            /* Concrete */
00722         204,                                            /* FerroCrete */
00723         204,                                            /* Building_Supplies */
00724         204,                                            /* Kevlar */
00725         204,                                            /* Waste */
00726         308,                                            /* Livestock */
00727         102,                                            /* Paper */
00728         1024,                                           /* XL_Gyro */
00729         2048,                                           /* HeavyDuty_Gyro */
00730         2048,                                           /* Compact_Gyro */
00731         2048,                                           /* Compact_HeatSink */
00732         204,                                            /* SearchLight */
00733 #ifdef BT_COMPLEXREPAIRS
00734         102,                                            /* Sensors_10 */
00735         204,                                            /* Sensors_20 */
00736         306,                                            /* Sensors_30 */
00737         408,                                            /* Sensors_40 */
00738         510,                                            /* Sensors_50 */
00739         612,                                            /* Sensors_60 */
00740         714,                                            /* Sensors_70 */
00741         816,                                            /* Sensors_80 */
00742         918,                                            /* Sensors_90 */
00743         1020,                                           /* Sensors_100 */
00744         102,                                            /* Myomer_10 */
00745         102,                                            /* Myomer_20 */
00746         102,                                            /* Myomer_30 */
00747         102,                                            /* Myomer_40 */
00748         102,                                            /* Myomer_50 */
00749         102,                                            /* Myomer_60 */
00750         102,                                            /* Myomer_70 */
00751         102,                                            /* Myomer_80 */
00752         102,                                            /* Myomer_90 */
00753         102,                                            /* Myomer_100 */
00754         102,                                            /* TripleMyomer_10 */
00755         102,                                            /* TripleMyomer_20 */
00756         102,                                            /* TripleMyomer_30 */
00757         102,                                            /* TripleMyomer_40 */
00758         102,                                            /* TripleMyomer_50 */
00759         102,                                            /* TripleMyomer_60 */
00760         102,                                            /* TripleMyomer_70 */
00761         102,                                            /* TripleMyomer_80 */
00762         102,                                            /* TripleMyomer_90 */
00763         102,                                            /* TripleMyomer_100 */
00764         128,                                            /* Internal_10 */
00765         128,                                            /* Internal_20 */
00766         128,                                            /* Internal_30 */
00767         128,                                            /* Internal_40 */
00768         128,                                            /* Internal_50 */
00769         128,                                            /* Internal_60 */
00770         128,                                            /* Internal_70 */
00771         128,                                            /* Internal_80 */
00772         128,                                            /* Internal_90 */
00773         128,                                            /* Internal_100 */
00774         128,                                            /* ES_Internal_10 */
00775         128,                                            /* ES_Internal_20 */
00776         128,                                            /* ES_Internal_30 */
00777         128,                                            /* ES_Internal_40 */
00778         128,                                            /* ES_Internal_50 */
00779         128,                                            /* ES_Internal_60 */
00780         128,                                            /* ES_Internal_70 */
00781         128,                                            /* ES_Internal_80 */
00782         128,                                            /* ES_Internal_90 */
00783         128,                                            /* ES_Internal_100 */
00784         102,                                            /* JumpJet_10 */
00785         204,                                            /* JumpJet_20 */
00786         306,                                            /* JumpJet_30 */
00787         408,                                            /* JumpJet_40 */
00788         510,                                            /* JumpJet_50 */
00789         612,                                            /* JumpJet_60 */
00790         714,                                            /* JumpJet_70 */
00791         816,                                            /* JumpJet_80 */
00792         918,                                            /* JumpJet_90 */
00793         1020,                                           /* JumpJet_100 */
00794         8,                                                      /* UpperArmActuator_10 */
00795         8,                                                      /* UpperArmActuator_20 */
00796         8,                                                      /* UpperArmActuator_30 */
00797         8,                                                      /* UpperArmActuator_40 */
00798         8,                                                      /* UpperArmActuator_50 */
00799         8,                                                      /* UpperArmActuator_60 */
00800         8,                                                      /* UpperArmActuator_70 */
00801         8,                                                      /* UpperArmActuator_80 */
00802         8,                                                      /* UpperArmActuator_90 */
00803         8,                                                      /* UpperArmActuator_100 */
00804         8,                                                      /* LowerArmActuator_10 */
00805         8,                                                      /* LowerArmActuator_20 */
00806         8,                                                      /* LowerArmActuator_30 */
00807         8,                                                      /* LowerArmActuator_40 */
00808         8,                                                      /* LowerArmActuator_50 */
00809         8,                                                      /* LowerArmActuator_60 */
00810         8,                                                      /* LowerArmActuator_70 */
00811         8,                                                      /* LowerArmActuator_80 */
00812         8,                                                      /* LowerArmActuator_90 */
00813         8,                                                      /* LowerArmActuator_100 */
00814         8,                                                      /* HandActuator_10 */
00815         8,                                                      /* HandActuator_20 */
00816         8,                                                      /* HandActuator_30 */
00817         8,                                                      /* HandActuator_40 */
00818         8,                                                      /* HandActuator_50 */
00819         8,                                                      /* HandActuator_60 */
00820         8,                                                      /* HandActuator_70 */
00821         8,                                                      /* HandActuator_80 */
00822         8,                                                      /* HandActuator_90 */
00823         8,                                                      /* HandActuator_100 */
00824         8,                                                      /* UpperLegActuator_10 */
00825         8,                                                      /* UpperLegActuator_20 */
00826         8,                                                      /* UpperLegActuator_30 */
00827         8,                                                      /* UpperLegActuator_40 */
00828         8,                                                      /* UpperLegActuator_50 */
00829         8,                                                      /* UpperLegActuator_60 */
00830         8,                                                      /* UpperLegActuator_70 */
00831         8,                                                      /* UpperLegActuator_80 */
00832         8,                                                      /* UpperLegActuator_90 */
00833         8,                                                      /* UpperLegActuator_100 */
00834         8,                                                      /* LowerLegActuator_10 */
00835         8,                                                      /* LowerLegActuator_20 */
00836         8,                                                      /* LowerLegActuator_30 */
00837         8,                                                      /* LowerLegActuator_40 */
00838         8,                                                      /* LowerLegActuator_50 */
00839         8,                                                      /* LowerLegActuator_60 */
00840         8,                                                      /* LowerLegActuator_70 */
00841         8,                                                      /* LowerLegActuator_80 */
00842         8,                                                      /* LowerLegActuator_90 */
00843         8,                                                      /* LowerLegActuator_100 */
00844         8,                                                      /* FootActuator_10 */
00845         8,                                                      /* FootActuator_20 */
00846         8,                                                      /* FootActuator_30 */
00847         8,                                                      /* FootActuator_40 */
00848         8,                                                      /* FootActuator_50 */
00849         8,                                                      /* FootActuator_60 */
00850         8,                                                      /* FootActuator_70 */
00851         8,                                                      /* FootActuator_80 */
00852         8,                                                      /* FootActuator_90 */
00853         8,                                                      /* FootActuator_100 */
00854         51,                                                     /* Engine_20 */
00855         102,                                            /* Engine_40 */
00856         153,                                            /* Engine_60 */
00857         204,                                            /* Engine_80 */
00858         255,                                            /* Engine_100 */
00859         306,                                            /* Engine_120 */
00860         357,                                            /* Engine_140 */
00861         408,                                            /* Engine_160 */
00862         459,                                            /* Engine_180 */
00863         510,                                            /* Engine_200 */
00864         561,                                            /* Engine_220 */
00865         612,                                            /* Engine_240 */
00866         763,                                            /* Engine_260 */
00867         814,                                            /* Engine_280 */
00868         865,                                            /* Engine_300 */
00869         916,                                            /* Engine_320 */
00870         967,                                            /* Engine_340 */
00871         1018,                                           /* Engine_360 */
00872         1070,                                           /* Engine_380 */
00873         1020,                                           /* Engine_400 */
00874         51,                                                     /* XL_Engine_20 */
00875         102,                                            /* XL_Engine_40 */
00876         153,                                            /* XL_Engine_60 */
00877         204,                                            /* XL_Engine_80 */
00878         255,                                            /* XL_Engine_100 */
00879         306,                                            /* XL_Engine_120 */
00880         357,                                            /* XL_Engine_140 */
00881         408,                                            /* XL_Engine_160 */
00882         459,                                            /* XL_Engine_180 */
00883         510,                                            /* XL_Engine_200 */
00884         561,                                            /* XL_Engine_220 */
00885         612,                                            /* XL_Engine_240 */
00886         763,                                            /* XL_Engine_260 */
00887         814,                                            /* XL_Engine_280 */
00888         865,                                            /* XL_Engine_300 */
00889         916,                                            /* XL_Engine_320 */
00890         967,                                            /* XL_Engine_340 */
00891         1018,                                           /* XL_Engine_360 */
00892         1070,                                           /* XL_Engine_380 */
00893         1020,                                           /* XL_Engine_400 */
00894         51,                                                     /* ICE_Engine_20 */
00895         102,                                            /* ICE_Engine_40 */
00896         153,                                            /* ICE_Engine_60 */
00897         204,                                            /* ICE_Engine_80 */
00898         255,                                            /* ICE_Engine_100 */
00899         306,                                            /* ICE_Engine_120 */
00900         357,                                            /* ICE_Engine_140 */
00901         408,                                            /* ICE_Engine_160 */
00902         459,                                            /* ICE_Engine_180 */
00903         510,                                            /* ICE_Engine_200 */
00904         561,                                            /* ICE_Engine_220 */
00905         612,                                            /* ICE_Engine_240 */
00906         763,                                            /* ICE_Engine_260 */
00907         814,                                            /* ICE_Engine_280 */
00908         865,                                            /* ICE_Engine_300 */
00909         916,                                            /* ICE_Engine_320 */
00910         967,                                            /* ICE_Engine_340 */
00911         1018,                                           /* ICE_Engine_360 */
00912         1070,                                           /* ICE_Engine_380 */
00913         1020,                                           /* ICE_Engine_400 */
00914         51,                                                     /* Light_Engine_20 */
00915         102,                                            /* Light_Engine_40 */
00916         153,                                            /* Light_Engine_60 */
00917         204,                                            /* Light_Engine_80 */
00918         255,                                            /* Light_Engine_100 */
00919         306,                                            /* Light_Engine_120 */
00920         357,                                            /* Light_Engine_140 */
00921         408,                                            /* Light_Engine_160 */
00922         459,                                            /* Light_Engine_180 */
00923         510,                                            /* Light_Engine_200 */
00924         561,                                            /* Light_Engine_220 */
00925         612,                                            /* Light_Engine_240 */
00926         763,                                            /* Light_Engine_260 */
00927         814,                                            /* Light_Engine_280 */
00928         865,                                            /* Light_Engine_300 */
00929         916,                                            /* Light_Engine_320 */
00930         967,                                            /* Light_Engine_340 */
00931         1018,                                           /* Light_Engine_360 */
00932         1070,                                           /* Light_Engine_380 */
00933         1020,                                           /* Light_Engine_400 */
00934         128,                                            /* CO_Internal_10 */
00935         128,                                            /* CO_Internal_20 */
00936         128,                                            /* CO_Internal_30 */
00937         128,                                            /* CO_Internal_40 */
00938         128,                                            /* CO_Internal_50 */
00939         128,                                            /* CO_Internal_60 */
00940         128,                                            /* CO_Internal_70 */
00941         128,                                            /* CO_Internal_80 */
00942         128,                                            /* CO_Internal_90 */
00943         128,                                            /* CO_Internal_100 */
00944         128,                                            /* RE_Internal_10 */
00945         128,                                            /* RE_Internal_20 */
00946         128,                                            /* RE_Internal_30 */
00947         128,                                            /* RE_Internal_40 */
00948         128,                                            /* RE_Internal_50 */
00949         128,                                            /* RE_Internal_60 */
00950         128,                                            /* RE_Internal_70 */
00951         128,                                            /* RE_Internal_80 */
00952         128,                                            /* RE_Internal_90 */
00953         128,                                            /* RE_Internal_100 */
00954         1024,                                           /* Gyro_1 */
00955         2048,                                           /* Gyro_2 */
00956         3072,                                           /* Gyro_3 */
00957         4096,                                           /* Gyro_4 */
00958         1024,                                           /* XL_Gyro_1 */
00959         2048,                                           /* XL_Gyro_2 */
00960         3072,                                           /* XL_Gyro_3 */
00961         4096,                                           /* XL_Gyro_4 */
00962         1024,                                           /* HD_Gyro_1 */
00963         2048,                                           /* HD_Gyro_2 */
00964         3072,                                           /* HD_Gyro_3 */
00965         4096,                                           /* HD_Gyro_4 */
00966         1024,                                           /* Compact_Gyro_1 */
00967         2048,                                           /* Compact_Gyro_2 */
00968         3072,                                           /* Compact_Gyro_3 */
00969         4096,                                           /* Compact_Gyro_4 */
00970         51,                                                     /* XXL_Engine_20 */
00971         102,                                            /* XXL_Engine_40 */
00972         153,                                            /* XXL_Engine_60 */
00973         204,                                            /* XXL_Engine_80 */
00974         255,                                            /* XXL_Engine_100 */
00975         306,                                            /* XXL_Engine_120 */
00976         357,                                            /* XXL_Engine_140 */
00977         408,                                            /* XXL_Engine_160 */
00978         459,                                            /* XXL_Engine_180 */
00979         510,                                            /* XXL_Engine_200 */
00980         561,                                            /* XXL_Engine_220 */
00981         612,                                            /* XXL_Engine_240 */
00982         763,                                            /* XXL_Engine_260 */
00983         814,                                            /* XXL_Engine_280 */
00984         865,                                            /* XXL_Engine_300 */
00985         916,                                            /* XXL_Engine_320 */
00986         967,                                            /* XXL_Engine_340 */
00987         1018,                                           /* XXL_Engine_360 */
00988         1070,                                           /* XXL_Engine_380 */
00989         1020,                                           /* XXL_Engine_400 */
00990         51,                                                     /* Compact_Engine_20 */
00991         102,                                            /* Compact_Engine_40 */
00992         153,                                            /* Compact_Engine_60 */
00993         204,                                            /* Compact_Engine_80 */
00994         255,                                            /* Compact_Engine_100 */
00995         306,                                            /* Compact_Engine_120 */
00996         357,                                            /* Compact_Engine_140 */
00997         408,                                            /* Compact_Engine_160 */
00998         459,                                            /* Compact_Engine_180 */
00999         510,                                            /* Compact_Engine_200 */
01000         561,                                            /* Compact_Engine_220 */
01001         612,                                            /* Compact_Engine_240 */
01002         763,                                            /* Compact_Engine_260 */
01003         814,                                            /* Compact_Engine_280 */
01004         865,                                            /* Compact_Engine_300 */
01005         916,                                            /* Compact_Engine_320 */
01006         967,                                            /* Compact_Engine_340 */
01007         1018,                                           /* Compact_Engine_360 */
01008         1070,                                           /* Compact_Engine_380 */
01009         1020,                                           /* Compact_Engine_400 */
01010 #endif
01011 };
01012 #endif /* BT_PART_WEIGHTS */
01013 
01014 #ifdef BT_ADVANCED_ECON
01015 unsigned long long int specialcost[SPECIALCOST_SIZE] = { 0 };
01016 unsigned long long int ammocost[AMMOCOST_SIZE] = { 0 };
01017 unsigned long long int weapcost[WEAPCOST_SIZE] = { 0 };
01018 unsigned long long int cargocost[CARGOCOST_SIZE] = { 0 };
01019 unsigned long long int bombcost[BOMBCOST_SIZE] = { 0 };
01020 #endif
01021 
01022 int count_special_items()
01023 {
01024         int i = 0;
01025 
01026         while (internals[i])
01027                 i++;
01028         return i;
01029 }
01030 
01031 char *section_configs[] = {
01032         "Case", "Destroyed",
01033         NULL
01034 };
01035 
01036 char *move_types[] = {
01037         "Biped", "Track", "Wheel", "Hover", "VTOL", "Hull", "Foil", "Fly",
01038         "Quad",
01039         "Sub", "None",
01040         NULL
01041 };
01042 
01043 char *mech_types[] = {
01044         "Mech", "Vehicle", "VTOL", "Naval", "Spheroid_DropShip", "AeroFighter",
01045         "Mechwarrior", "Aerodyne_DropShip", "Battlesuit", NULL
01046 };
01047 
01048 char *crit_fire_modes[] = {
01049         "Destroyed",
01050         "Disabled",
01051         "Broken",
01052         "Damaged",
01053         "OnTC",
01054         "RearMount",
01055         "Hotload",
01056         "Halfton",
01057         "OneShot",
01058         "OneShot_Used",
01059         "UltraMode",
01060         "RapidFire",
01061         "Gattling",
01062         "Rotary_TwoShot",
01063         "Rotary_FourShot",
01064         "Rotary_SixShot",
01065         "Heat",
01066         "BackPack",
01067         "Jettisoned",
01068         "OmniBase",
01069         NULL
01070 };
01071 
01072 char *crit_ammo_modes[] = {
01073         "LBX/Cluster",
01074         "Artemis/Mine",
01075         "Narc/Smoke",
01076         "Cluster",
01077         "Mine",
01078         "Smoke",
01079         "Inferno",
01080         "Swarm",
01081         "Swarm1",
01082         "iNarc_Explosive",
01083         "iNarc_Haywire",
01084         "iNarc_ECM",
01085         "iNarc_Nemesis",
01086         "AP",
01087         "Flechette",
01088         "Incendiary",
01089         "Precision",
01090         "Stinger",
01091         NULL
01092 };
01093 
01094 /* 'specials' is *full* */
01095 char *specials[] = {
01096         "TripleMyomerTech",
01097         "CL_AMS",
01098         "IS_AMS",
01099         "DoubleHS",
01100         "Masc",
01101         "Clan",
01102         "FlipArms",
01103         "C3MasterTech",
01104         "C3SlaveTech",
01105         "ArtemisIV",
01106         "ECM",
01107         "BeagleProbe",
01108         "SalvageTech",
01109         "CargoTech",
01110         "SearchLight",
01111         "LoaderTech",
01112         "AntiAircraft",
01113         "NoSensors",
01114         "SS_Ability",
01115         "FerroFibrous_Tech",
01116         "EndoSteel_Tech",
01117         "XLEngine_Tech",
01118         "ICEEngine_Tech",
01119         "LifterTech",
01120         "LightEngine_Tech",
01121         "XXL_Tech",
01122         "CompactEngine_Tech",
01123         "ReinforcedInternal_Tech",
01124         "CompositeInternal_Tech",
01125         "HardenedArmor_Tech",
01126         "CritProof_Tech",
01127         NULL
01128 };
01129 
01130 char *specialsabrev[] = {
01131         "TSM", "CLAMS", "ISAMS", "DHS", "MASC", "CLTECH", "FA", "C3M", "C3S",
01132         "AIV", "ECM", "BAP", "SAL", "CAR", "SL", "LOAD", "AA", "NOSEN", "SS",
01133         "FF", "ES", "XL", "ICE", "LIFT", "LENG", "XXL", "CENG", "RINT", "CINT",
01134         "HARM", "CP",
01135         NULL
01136 };
01137 /* 'specials' is *full* */
01138 
01139 char *specials2[] = {
01140         "StealthArmor_Tech",
01141         "HvyFerroFibrous_Tech",
01142         "LaserRefArmor_Tech",
01143         "ReactiveArmor_Tech",
01144         "NullSigSys_Tech",
01145         "C3I_Tech",
01146         "SuperCharger_Tech",
01147         "ImprovedJJ_Tech",
01148         "MechanicalJJ_Tech",
01149         "CompactHS",
01150         "LaserHS_Tech",
01151         "BloodhoundProbe_Tech",
01152         "AngelECM_Tech",
01153         "WatchDog_Tech",
01154         "LtFerroFibrous_Tech",
01155         "TAG_Tech",
01156         "OmniMech_Tech",
01157         "ArtemisV_Tech",
01158         "Camo_Tech",
01159         "Carrier_Tech",
01160         "Waterproof_Tech",
01161         "XLGyro_Tech",
01162         "HDGyro_Tech",
01163         "CompactGyro_Tech",
01164         "TargComp_Tech",
01165         NULL
01166 };
01167 
01168 char *specialsabrev2[] = {
01169         "STHA", "HFF", "LRARM", "REACTARM", "NULL", "C3I", "SCHARGE",
01170         "IJJ", "MJJ", "CHS", "LHS", "BLP", "AECM", "WDOG", "LFF",
01171         "TAG", "OMNI", "AV",
01172         "CAMO",
01173         "CART",
01174         "WPRF",
01175         "XLGRYO", "HDGYRO", "CGYRO",
01176         "TCOMP",
01177         NULL
01178 };
01179 
01180 char *infantry_specials[] = {
01181         "Swarm_Attack_Tech",
01182         "Mount_Friends_Tech",
01183         "AntiLeg_Attack_Tech",
01184         "CS_Purifier_Stealth_Tech",
01185         "DC_Kage_Stealth_Tech",
01186         "FWL_Achileus_Stealth_Tech",
01187         "FC_Infiltrator_Stealth_Tech",
01188         "FC_InfiltratorII_Stealth_Tech",
01189         "Must_Jettison_Pack_Tech",
01190         "Can_Jettison_Pack_Tech",
01191         NULL
01192 };
01193 
01194 int compare_array(char *list[], char *command)
01195 {
01196         int x;
01197 
01198         if(!list)
01199                 return -1;
01200         for(x = 0; list[x]; x++)
01201                 if(!strcasecmp(list[x], command))
01202                         return x;
01203 
01204         return -1;
01205 }
01206 
01207 char *one_arg(char *argument, char *first_arg)
01208 {
01209         if(isspace(*argument))
01210                 for(argument++; isspace(*argument); argument++);
01211 
01212         while (*argument && !isspace(*argument))
01213                 *(first_arg++) = *(argument++);
01214         *first_arg = '\0';
01215         return argument;
01216 }
01217 
01218 char *one_arg_delim(char *argument, char *first_arg)
01219 {
01220         if(isspace(*argument) || (*argument == '|'))
01221                 for(argument++; (isspace(*argument) || (*argument == '|'));
01222                         argument++);
01223 
01224         while (*argument && (!(*argument == '|')))
01225                 *(first_arg++) = *(argument++);
01226 
01227         *first_arg = '\0';
01228         return argument;
01229 }
01230 
01231 char *BuildBitString(char *bitdescs[], int data)
01232 {
01233         static char crit[MAX_STRING_LENGTH];
01234         int bv;
01235         int x;
01236 
01237         crit[0] = 0;
01238         for(x = 0; bitdescs[x]; x++) {
01239                 bv = 1U << x;
01240                 if(data & bv) {
01241                         strcat(crit, bitdescs[x]);
01242                         strcat(crit, " ");
01243                 }
01244         }
01245         if((x = strlen(crit)) > 0 && crit[x - 1] == ' ')
01246                 crit[x - 1] = '\0';
01247         return crit;
01248 }
01249 
01250 char *BuildBitString2(char *bitdescs[], char *bitdescs2[], int data,
01251                                           int data2)
01252 {
01253         static char crit[MAX_STRING_LENGTH];
01254         int bv;
01255         int x;
01256 
01257         crit[0] = 0;
01258 
01259         for(x = 0; bitdescs[x]; x++) {
01260                 bv = 1U << x;
01261                 if(data & bv) {
01262                         strcat(crit, bitdescs[x]);
01263                         strcat(crit, " ");
01264                 }
01265         }
01266 
01267         for(x = 0; bitdescs2[x]; x++) {
01268                 bv = 1U << x;
01269                 if(data2 & bv) {
01270                         strcat(crit, bitdescs2[x]);
01271                         strcat(crit, " ");
01272                 }
01273         }
01274 
01275         if((x = strlen(crit)) > 0 && crit[x - 1] == ' ') {
01276                 crit[x - 1] = '\0';
01277 
01278         }
01279 
01280         return crit;
01281 }
01282 
01283 char *BuildBitStringwdelim2(char *bitdescs[], char *bitdescs2[], int data,
01284                                           int data2)
01285 {
01286         static char crit[MAX_STRING_LENGTH];
01287         int bv;
01288         int x;
01289 
01290         crit[0] = 0;
01291 
01292         for(x = 0; bitdescs[x]; x++) {
01293                 bv = 1U << x;
01294                 if(data & bv) {
01295                         strcat(crit, bitdescs[x]);
01296                         strcat(crit, "|");
01297                 }
01298         }
01299 
01300         for(x = 0; bitdescs2[x]; x++) {
01301                 bv = 1U << x;
01302                 if(data2 & bv) {
01303                         strcat(crit, bitdescs2[x]);
01304                         strcat(crit, "|");
01305                 }
01306         }
01307 
01308         if((x = strlen(crit)) > 0 && crit[x - 1] == '|') {
01309                 crit[x - 1] = '\0';
01310 
01311         }
01312 
01313         return crit;
01314 }
01315 
01316 char *BuildBitString3(char *bitdescs[], char *bitdescs2[],
01317                                           char *bitdescs3[], int data, int data2, int data3)
01318 {
01319         static char crit[MAX_STRING_LENGTH];
01320         int bv;
01321         int x;
01322 
01323         crit[0] = 0;
01324 
01325         for(x = 0; bitdescs[x]; x++) {
01326                 bv = 1U << x;
01327                 if(data & bv) {
01328                         strcat(crit, bitdescs[x]);
01329                         strcat(crit, " ");
01330                 }
01331         }
01332 
01333         for(x = 0; bitdescs2[x]; x++) {
01334                 bv = 1U << x;
01335                 if(data2 & bv) {
01336                         strcat(crit, bitdescs2[x]);
01337                         strcat(crit, " ");
01338                 }
01339         }
01340 
01341         for(x = 0; bitdescs3[x]; x++) {
01342                 bv = 1U << x;
01343                 if(data3 & bv) {
01344                         strcat(crit, bitdescs3[x]);
01345                         strcat(crit, " ");
01346                 }
01347         }
01348 
01349         if((x = strlen(crit)) > 0 && crit[x - 1] == ' ')
01350                 crit[x - 1] = '\0';
01351 
01352         return crit;
01353 }
01354 
01355 #define QDM(a) case I2Special(a): return 1
01356 static int InvalidVehicleItem(MECH * mech, int x, int y)
01357 {
01358         int t;
01359 
01360         t = GetPartType(mech, x, y);
01361         switch (t) {
01362                 QDM(SHOULDER_OR_HIP);
01363                 QDM(UPPER_ACTUATOR);
01364                 QDM(LOWER_ACTUATOR);
01365                 QDM(HAND_OR_FOOT_ACTUATOR);
01366                 QDM(ENGINE);
01367                 QDM(GYRO);
01368                 QDM(JUMP_JET);
01369         }
01370         return 0;
01371 }
01372 
01373 extern int num_def_weapons;
01374 int internal_count = sizeof(internals) / sizeof(char *) - 1;
01375 int cargo_count = sizeof(cargo) / sizeof(char *) - 1;
01376 
01377 #ifndef CLAN_SUPPORT
01378 #define CLCH(a) do { if (MechWeapons[a].special & (CLAT)) return NULL; } while (0)
01379 #else
01380 #define CLCH(a) \
01381 do { if (temp_brand_flag) { if ((!mudconf.btech_parts) || (MechWeapons[a].special & CLAT)) return NULL; else if (MechWeapons[a].special & CLAT) isclan=1; }} while (0)
01382 #endif
01383 
01384 extern int temp_brand_flag;
01385 
01386 static char *part_figure_out_name_sub(int i, int j)
01387 {
01388         static char buf[MBUF_SIZE];
01389         int isclan = 0;
01390 
01391         if(!i)
01392                 return NULL;
01393         if(IsWeapon(i) && i < I2Weapon(num_def_weapons)) {
01394                 CLCH(Weapon2I(i));
01395                 return &MechWeapons[Weapon2I(i)].name[(j && !isclan) ? 3 : 0];
01396         } else if(IsAmmo(i) && i < I2Ammo(num_def_weapons)) {
01397                 CLCH(Ammo2WeaponI(i));
01398                 if(MechWeapons[Ammo2WeaponI(i)].type != TBEAM &&
01399                    MechWeapons[Ammo2WeaponI(i)].type != THAND &&
01400                    !(MechWeapons[Ammo2WeaponI(i)].special & PCOMBAT)) {
01401                         sprintf(buf, "Ammo_%s", &MechWeapons[Ammo2WeaponI(i)].name[(j
01402                                                                                                                                                 &&
01403                                                                                                                                                 !isclan)
01404                                                                                                                                            ? 3 :
01405                                                                                                                                            0]);
01406                         return buf;
01407                 }
01408         } else if(!temp_brand_flag) {
01409                 if(IsBomb(i)) {
01410                         sprintf(buf, "Bomb_%s", bomb_name(Bomb2I(i)));
01411                         return buf;
01412                 } else if(IsSpecial(i) && i < I2Special(internal_count))
01413                         return internals[Special2I(i)];
01414                 else if(IsCargo(i) && i < I2Cargo(cargo_count))
01415                         return cargo[Cargo2I(i)];
01416         }
01417         return NULL;
01418 }
01419 
01420 char *my_shortform(char *buf)
01421 {
01422         static char buf2[MBUF_SIZE];
01423         char *c, *d;
01424 
01425         if(!buf)
01426                 return NULL;
01427         if(strlen(buf) <= 4 && !strchr(buf, '/'))
01428                 strcpy(buf2, buf);
01429         else {
01430                 for(c = buf, d = buf2; *c; c++)
01431                         if(isdigit(*c) || isupper(*c) || *c == '_')
01432                                 *d++ = *c;
01433                 *d = 0;
01434                 if(strlen(buf2) == 1)
01435                         strcat(d, tprintf("%c", buf[1]));
01436         }
01437         return buf2;
01438 }
01439 
01440 #undef CLCH
01441 #ifdef CLAN_SUPPORT
01442 #define CLCH(a) ((!strncasecmp(MechWeapons[a].name, "CL.", 2)) ? 0 : 3)
01443 #else
01444 #define CLCH(a) 3
01445 #endif
01446 
01447 char *part_figure_out_shname(int i)
01448 {
01449         char buf[MBUF_SIZE];
01450 
01451         if(!i)
01452                 return NULL;
01453         buf[0] = 0;
01454         if(IsWeapon(i) && i < I2Weapon(num_def_weapons)) {
01455                 strcpy(buf, &MechWeapons[Weapon2I(i)].name[CLCH(Weapon2I(i))]);
01456         } else if(IsAmmo(i) && i < I2Ammo(num_def_weapons)) {
01457                 sprintf(buf, "Ammo_%s",
01458                                 &MechWeapons[Ammo2WeaponI(i)].name[CLCH(Ammo2WeaponI(i))]);
01459         } else if(IsBomb(i))
01460                 sprintf(buf, "Bomb_%s", bomb_name(Bomb2I(i)));
01461         else if(IsSpecial(i) && i < I2Special(internal_count))
01462                 strcpy(buf, internals[Special2I(i)]);
01463         if(IsCargo(i) && i < I2Cargo(cargo_count))
01464                 strcpy(buf, cargo[Cargo2I(i)]);
01465         if(!buf[0])
01466                 return NULL;
01467         return my_shortform(buf);
01468 }
01469 
01470 char *part_figure_out_name(int i)
01471 {
01472         return part_figure_out_name_sub(i, 0);
01473 }
01474 
01475 char *part_figure_out_sname(int i)
01476 {
01477         return part_figure_out_name_sub(i, 1);
01478 }
01479 
01480 #define TCAble(t) \
01481         ((MechWeapons[Weapon2I(t)].type == TBEAM || MechWeapons[Weapon2I(t)].type == TAMMO) && \
01482         strcmp(&MechWeapons[Weapon2I(t)].name[3], "Flamer") && \
01483         strcmp(&MechWeapons[Weapon2I(t)].name[3], "MachineGun") && \
01484         strcmp(&MechWeapons[Weapon2I(t)].name[3], "HeavyMachineGun") && \
01485         !(MechWeapons[Weapon2I(t)].special & PCOMBAT))
01486 
01487 static int dump_item(FILE * fp, MECH * mech, int x, int y)
01488 {
01489         char crit[32];
01490         int y1;
01491         int flaggo = 0;
01492         int z;
01493         int wFireModes, wAmmoModes;
01494 
01495         if(!GetPartType(mech, x, y))
01496                 return 1;
01497         if(MechType(mech) != CLASS_MECH && InvalidVehicleItem(mech, x, y))
01498                 return 1;
01499         for(y1 = y + 1; y1 < 12; y1++) {
01500                 if(GetPartType(mech, x, y1) != GetPartType(mech, x, y))
01501                         break;
01502                 if(GetPartData(mech, x, y1) != GetPartData(mech, x, y))
01503                         break;
01504                 if(GetPartFireMode(mech, x, y1) != GetPartFireMode(mech, x, y))
01505                         break;
01506                 if(GetPartAmmoMode(mech, x, y1) != GetPartAmmoMode(mech, x, y))
01507                         break;
01508                 if(mudconf.btech_parts)
01509                         if(GetPartBrand(mech, x, y1) != GetPartBrand(mech, x, y))
01510                                 break;
01511         }
01512         y1--;
01513         if(IsWeapon(GetPartType(mech, x, y))) {
01514                 /* Nonbeams, or flamers don't have TC */
01515                 if(!TCAble(GetPartType(mech, x, y)))
01516                         flaggo = ON_TC;
01517                 if(((y1 - y) + 1) > (z =
01518                                                          GetWeaponCrits(mech,
01519                                                                                         Weapon2I(GetPartType
01520                                                                                                          (mech, x, y)))))
01521                         y1 = y + z - 1;
01522         }
01523         if(y != y1)
01524                 snprintf(crit, 32, "CRIT_%d-%d", y + 1, y1 + 1);
01525         else
01526                 snprintf(crit, 32, "CRIT_%d", y + 1);
01527 
01528         wFireModes = GetPartFireMode(mech, x, y);
01529         wFireModes &= ~flaggo;
01530         wAmmoModes = GetPartAmmoMode(mech, x, y);
01531 
01532         if(IsWeapon(GetPartType(mech, x, y)))
01533                 fprintf(fp, "    %s               { %s - %s %s}\n", crit,
01534                                 get_parts_vlong_name(GetPartType(mech, x, y), 0),
01535                                 (wFireModes ||
01536                                  wAmmoModes) ? BuildBitStringwdelim2(crit_fire_modes,
01537                                                                                            crit_ammo_modes, wFireModes,
01538                                                                                            wAmmoModes) : "-",
01539                                 !mudconf.btech_parts ? "" : tprintf("%d ",
01540                                                                                                         GetPartBrand(mech, x,
01541                                                                                                                                  y)));
01542         else if(IsAmmo(MechSections(mech)[x].criticals[y].type))
01543                 fprintf(fp, "    %s               { %s %d %s - }\n", crit,
01544                                 get_parts_vlong_name(GetPartType(mech, x, y), 0),
01545                                 FullAmmo(mech, x, y),
01546                                 (MechSections(mech)[x].criticals[y].firemode ||
01547                                  MechSections(mech)[x].criticals[y].
01548                                  ammomode) ? BuildBitStringwdelim2(crit_fire_modes,
01549                                                                                          crit_ammo_modes,
01550                                                                                          MechSections(mech)[x].
01551                                                                                          criticals[y].firemode,
01552                                                                                          MechSections(mech)[x].
01553                                                                                          criticals[y].ammomode) : "-");
01554         else if(IsBomb(MechSections(mech)[x].criticals[y].type))
01555                 fprintf(fp, "    %s               { %s - - - }\n", crit,
01556                                 get_parts_vlong_name(GetPartType(mech, x, y), 0));
01557         else {
01558                 fprintf(fp, "    %s               { %s - - %s}\n", crit,
01559                                 get_parts_vlong_name(GetPartType(mech, x, y), 0),
01560                                 !mudconf.btech_parts ? "" : tprintf("%d ",
01561                                                                                                         GetPartBrand(mech, x,
01562                                                                                                                                  y)));
01563         }
01564         return (y1 - y + 1);
01565 }
01566 
01567 void dump_locations(FILE * fp, MECH * mech, const char *locdesc[])
01568 {
01569         int x, y, l;
01570         char buf[512];
01571         char *ch;
01572 
01573         for(x = 0; locdesc[x]; x++) {
01574                 if(!GetSectOInt(mech, x))
01575                         continue;
01576                 strcpy(buf, locdesc[x]);
01577                 for(ch = buf; *ch; ch++)
01578                         if(*ch == ' ')
01579                                 *ch = '_';
01580                 fprintf(fp, "%s\n", buf);
01581                 if(GetSectOArmor(mech, x))
01582                         fprintf(fp, "  Armor            { %d }\n", GetSectOArmor(mech,
01583                                                                                                                                          x));
01584                 if(GetSectOInt(mech, x))
01585                         fprintf(fp, "  Internals        { %d }\n", GetSectOInt(mech, x));
01586                 if(GetSectORArmor(mech, x))
01587                         fprintf(fp, "  Rear             { %d }\n", GetSectORArmor(mech,
01588                                                                                                                                           x));
01589 #if 0                                                   /* Shouldn't be neccessary to save at all */
01590                 fprintf(fp, "  Recycle          { %d }\n",
01591                                 MechSections(mech)[x].recycle);
01592 #endif
01593                 y = MechSections(mech)[x].config;
01594                 y &= ~CASE_TECH;
01595                 if(y)
01596                         fprintf(fp, "  Config           { %s }\n",
01597                                         BuildBitString(section_configs, y));
01598                 l = CritsInLoc(mech, x);
01599                 for(y = 0; y < l;)
01600                         y += dump_item(fp, mech, x, y);
01601         }
01602 }
01603 
01604 float generic_computer_multiplier(MECH * mech)
01605 {
01606         switch (MechComputer(mech)) {
01607         case 1:
01608                 return 0.8;
01609         case 2:
01610                 return 1;
01611         case 3:
01612                 return 1.25;
01613         case 4:
01614                 return 1.5;
01615         case 5:
01616                 return 1.75;
01617         }
01618         return 0;
01619 }
01620 
01621 int generic_radio_type(int i, int isClan)
01622 {
01623         int f = DEFAULT_FREQS;
01624 
01625         if(isClan || i >= 4)
01626                 f += FREQS * RADIO_RELAY;
01627         if(i < 3)
01628                 f -= (3 - i) * 2 - 1;   /* 2 or 4 */
01629         else
01630                 f += (i - 3) * 3;               /* 5 / 8 / 11 */
01631         return f;
01632 }
01633 
01634 float generic_radio_multiplier(MECH * mech)
01635 {
01636         switch (MechRadio(mech)) {
01637         case 1:
01638                 return 0.8;
01639         case 2:
01640                 return 1;
01641         case 3:
01642                 return 1.25;
01643         case 4:
01644                 return 1.5;
01645         case 5:
01646                 return 1.75;
01647         }
01648         return 0.0;
01649 }
01650 
01651 #define MechComputersScanRange(mech) \
01652 (generic_computer_multiplier(mech) * DEFAULT_SCANRANGE)
01653 
01654 #define MechComputersLRSRange(mech) \
01655 (generic_computer_multiplier(mech) * DEFAULT_LRSRANGE)
01656 
01657 #define MechComputersTacRange(mech) \
01658 (generic_computer_multiplier(mech) * DEFAULT_TACRANGE)
01659 
01660 #define MechComputersRadioRange(mech) \
01661 (DEFAULT_RADIORANGE * generic_radio_multiplier(mech))
01662 
01663 void computer_conversion(MECH * mech)
01664 {
01665         int l = 0;
01666 
01667         switch (MechScanRange(mech)) {
01668         case 20:
01669                 l = 2;
01670                 break;
01671         case 25:
01672                 l = 3;
01673                 break;
01674         case 30:
01675                 l = 4;
01676                 break;
01677         }
01678         if(l) {
01679                 MechComputer(mech) = l;
01680                 MechScanRange(mech) = MechComputersScanRange(mech);
01681                 MechTacRange(mech) = MechComputersTacRange(mech);
01682                 MechLRSRange(mech) = MechComputersLRSRange(mech);
01683                 MechRadioRange(mech) = MechComputersRadioRange(mech);
01684         }
01685 }
01686 
01687 void try_to_find_name(char *mechref, MECH * mech)
01688 {
01689         const char *c;
01690 
01691         if((c = find_mechname_by_mechref(mechref)))
01692                 strcpy(MechType_Name(mech), c);
01693 }
01694 
01695 int DefaultFuelByType(MECH * mech)
01696 {
01697         int mod = 2;
01698 
01699         switch (MechType(mech)) {
01700         case CLASS_VTOL:
01701                 return 2000 * mod;
01702         case CLASS_AERO:
01703                 return 1200 * mod;
01704         case CLASS_DS:
01705         case CLASS_SPHEROID_DS:
01706                 return 3600 * mod;
01707         }
01708         return 0;
01709 }
01710 
01711 int save_template(dbref player, MECH * mech, char *reference, char *filename)
01712 {
01713         FILE *fp;
01714         int x, x2, inf_x;
01715         char **locs;
01716         char *d, *c = ctime(&mudstate.now);
01717 
01718         if(!MechComputer(mech))
01719                 computer_conversion(mech);
01720         if(!MechType_Name(mech)[0])
01721                 try_to_find_name(reference, mech);
01722         if(!(fp = fopen(filename, "w")))
01723                 return -1;
01724         if(MechType_Name(mech)[0])
01725                 fprintf(fp, "Name             { %s }\n", MechType_Name(mech));
01726         fprintf(fp, "Reference        { %s }\n", reference);
01727         fprintf(fp, "Type             { %s }\n",
01728                         mech_types[(short) MechType(mech)]);
01729         fprintf(fp, "Move_Type        { %s }\n",
01730                         move_types[(short) MechMove(mech)]);
01731         fprintf(fp, "Tons             { %d }\n", MechTons(mech));
01732         if((d = strrchr(c, '\n')))
01733                 *d = 0;
01734         fprintf(fp, "Comment          { Saved by: %s(#%d) at %s }\n",
01735                         Name(player), player, c);
01736 #define SILLY_UTTERANCE(ran,cran,dran,name) \
01737   if ((!MechComputer(mech) && ran != dran) || \
01738       (MechComputer(mech) && ran != cran)) \
01739       fprintf(fp, "%-16s { %d }\n", name, ran)
01740 
01741         SILLY_UTTERANCE(MechTacRange(mech), MechComputersTacRange(mech),
01742                                         DEFAULT_TACRANGE, "Tac_Range");
01743         SILLY_UTTERANCE(MechLRSRange(mech), MechComputersLRSRange(mech),
01744                                         DEFAULT_LRSRANGE, "LRS_Range");
01745         SILLY_UTTERANCE(MechScanRange(mech), MechComputersScanRange(mech),
01746                                         DEFAULT_SCANRANGE, "Scan_Range");
01747         SILLY_UTTERANCE(MechRadioRange(mech), MechComputersRadioRange(mech),
01748                                         DEFAULT_RADIORANGE, "Radio_Range");
01749 
01750 #define SILLY_OUTPUT(def,now,name) \
01751   if ((def) != (now)) \
01752      fprintf(fp, "%-16s { %d }\n", name, now)
01753 
01754         SILLY_OUTPUT(DEFAULT_COMPUTER, MechComputer(mech), "Computer");
01755         SILLY_OUTPUT(DEFAULT_RADIO, MechRadio(mech), "Radio");
01756         SILLY_OUTPUT((MechSpecials(mech) & ICE_TECH) ? 0 : DEFAULT_HEATSINKS,
01757                                  MechRealNumsinks(mech), "Heat_Sinks");
01758         SILLY_OUTPUT(generic_radio_type(MechRadio(mech),
01759                                                                         MechSpecials(mech) & CLAN_TECH),
01760                                  MechRadioType(mech), "RadioType");
01761         SILLY_OUTPUT(2000, MechBV(mech), "Mech_BV");
01762         SILLY_OUTPUT(2000, CargoSpace(mech), "Cargo_Space");
01763         SILLY_OUTPUT(0, CarMaxTon(mech), "Max_Ton");
01764         SILLY_OUTPUT(2000, MechMaxSuits(mech), "Max_Suits");
01765         SILLY_OUTPUT(0, AeroSIOrig(mech), "SI");
01766 
01767         SILLY_OUTPUT(DefaultFuelByType(mech), AeroFuelOrig(mech), "Fuel");
01768 
01769         fprintf(fp, "Max_Speed        { %.2f }\n", MechMaxSpeed(mech));
01770         if(MechJumpSpeed(mech) > 0.0)
01771                 fprintf(fp, "Jump_Speed       { %.2f }\n", MechJumpSpeed(mech));
01772         x = MechSpecials(mech);
01773         x2 = MechSpecials2(mech);
01774         /* Remove AMS'es, they're re-generated back on loadtime */
01775         x &= ~(CL_ANTI_MISSILE_TECH | IS_ANTI_MISSILE_TECH | SS_ABILITY);
01776         x &=                                            /* Calculated at load-time */
01777                 ~(BEAGLE_PROBE_TECH | TRIPLE_MYOMER_TECH | MASC_TECH | ECM_TECH |
01778                   C3_SLAVE_TECH | C3_MASTER_TECH | ARTEMIS_IV_TECH | ES_TECH |
01779                   FF_TECH);
01780 
01781         if(MechType(mech) == CLASS_MECH)
01782                 x &= ~(XL_TECH | XXL_TECH | CE_TECH | LE_TECH);
01783 
01784         /* Get rid of our specials2 */
01785         x2 &=
01786                 ~(STEALTH_ARMOR_TECH | NULLSIGSYS_TECH | ANGEL_ECM_TECH |
01787                   HVY_FF_ARMOR_TECH | LT_FF_ARMOR_TECH | TAG_TECH | C3I_TECH |
01788                   BLOODHOUND_PROBE_TECH | TCOMP_TECH);
01789 
01790         if(x || x2)
01791                 fprintf(fp, "Specials         { %s }\n", BuildBitString2(specials,
01792                                                                                                                                  specials2, x,
01793                                                                                                                                  x2));
01794 
01795         inf_x = MechInfantrySpecials(mech);
01796 
01797         if(inf_x)
01798                 fprintf(fp, "InfantrySpecials { %s }\n",
01799                                 BuildBitString(infantry_specials, inf_x));
01800 
01801         if((locs = (char **)ProperSectionStringFromType(MechType(mech), MechMove(mech)))) {
01802                 dump_locations(fp, mech, (const char **)locs);
01803                 fclose(fp);
01804                 return 0;
01805         }
01806         fclose(fp);
01807         return -1;
01808 }
01809 
01810 char *read_desc(FILE * fp, char *data)
01811 {
01812         char keep[MAX_STRING_LENGTH + 500];
01813         char *t, *tmp;
01814         char *point;
01815         int length = 0;
01816         static char buf[MAX_STRING_LENGTH];
01817 
01818         keep[0] = '\0';
01819         if((tmp = strchr(data, '{'))) {
01820                 fscanf(fp, "\n");
01821                 while (isspace(*(++tmp)));
01822                 if((t = strchr(tmp, '}'))) {
01823                         while (isspace(*(t--)));
01824                         *(t++) = '\0';
01825                         length = strlen(tmp);
01826                         strcpy(buf, tmp);
01827                         return buf;
01828                 } else {
01829                         strcpy(keep, tmp);
01830                         strcat(keep, "\r\n");
01831                         t = tmp + strlen(tmp) - 1;
01832                         length = strlen(t);
01833                         while (fgets(data, 512, fp)) {
01834                                 fscanf(fp, "\n");
01835                                 if((tmp = strchr(data, '}')) != NULL) {
01836                                         *tmp = 0;
01837                                         length += strlen(data);
01838                                         strcat(keep, data);
01839                                         break;
01840                                 } else {
01841                                         point = data + strlen(data) - 1;
01842                                         *(point++) = '\r';
01843                                         *(point++) = '\n';
01844                                         *point = '\0';
01845                                         strcat(keep, data);
01846                                         length += strlen(data);
01847                                 }
01848                         }
01849                 }
01850         }
01851         strcpy(buf, keep);
01852         return buf;
01853 }
01854 
01855 int find_section(char *cmd, int type, int mtype)
01856 {
01857     char section[20];
01858     char *ch;
01859     char **locs;
01860 
01861     strcpy(section, cmd);
01862     for(ch = section; *ch; ch++)
01863         if(*ch == '_')
01864             *ch = ' ';
01865     locs = (char **)ProperSectionStringFromType(type, mtype);
01866     return compare_array((char **) locs, section);
01867     return -1; // Who's retarded? not me!
01868 }
01869 
01870 long BuildBitVector(char **list, char *line)
01871 {
01872         long bv = 0;
01873         int temp;
01874         char buf[30];
01875 
01876         if(!strcasecmp(line, "-"))
01877                 return 0;
01878 
01879         while (*line) {
01880                 line = one_arg(line, buf);
01881                 if((temp = compare_array(list, buf)) == -1)
01882                         return -1;
01883                 bv |= 1U << temp;
01884         }
01885         return bv;
01886 }
01887 
01888 long BuildBitVectorWithDelim(char **list, char *line)
01889 {
01890         long bv = 0;
01891         int temp;
01892         char buf[30];
01893 
01894         if(!strcasecmp(line, "-"))
01895                 return 0;
01896 
01897         while (*line) {
01898                 line = one_arg_delim(line, buf);
01899 
01900                 if((temp = compare_array(list, buf)) == -1)
01901                         return -1;
01902 
01903                 bv |= 1U << temp;
01904         }
01905 
01906         return bv;
01907 }
01908 
01909 long BuildBitVectorNoErr(char **list, char *line)
01910 {
01911         long bv = 0;
01912         int temp;
01913         char buf[30];
01914 
01915         if(!strcasecmp(line, "-"))
01916                 return 0;
01917 
01918         while (*line) {
01919                 line = one_arg(line, buf);
01920 
01921                 if((temp = compare_array(list, buf)) != -1)
01922                         bv |= 1U << temp;
01923         }
01924 
01925         return bv;
01926 }
01927 
01928 int CheckSpecialsList(char **specials, char **specials2, char *line)
01929 {
01930         int wSpecCheck = -1, wSpec2Check = -1;
01931         char buf[30];
01932 
01933         if(!strcasecmp(line, "-"))
01934                 return 0;
01935 
01936         while (*line) {
01937                 line = one_arg(line, buf);
01938 
01939                 if(specials)
01940                         wSpecCheck = compare_array(specials, buf);
01941 
01942                 if(specials2)
01943                         wSpec2Check = compare_array(specials2, buf);
01944 
01945                 if((wSpecCheck == -1) && (wSpec2Check == -1))
01946                         return 0;
01947         }
01948 
01949         return 1;
01950 }
01951 
01952 int WeaponIFromString(char *data)
01953 {
01954         int x = 0;;
01955 
01956         while (MechWeapons[x].name) {
01957                 if(!strcasecmp(MechWeapons[x].name, data))
01958                         return x + 1;           /* weapons start at 1 not 0 */
01959                 x++;
01960         }
01961         return -1;
01962 }
01963 
01964 int AmmoIFromString(char *data)
01965 {
01966         int x = 0;
01967         char *ptr;
01968 
01969         ptr = data;
01970         while (*ptr != '_')
01971                 ptr++;
01972         ptr++;
01973         while (MechWeapons[x].name) {
01974                 if(!strcasecmp(MechWeapons[x].name, ptr))
01975                         return x + 101;
01976                 x++;
01977         }
01978         return -1;
01979 }
01980 
01981 void update_specials(MECH * mech)
01982 {
01983         int x, y, t;
01984         int masc_count = 0;
01985         int c3_master_count = 0;
01986         int tsm_count = 0;
01987         int ff_count = 0;
01988         int es_count = 0;
01989         int tc_count = 0;
01990         int awcSthArmor[NUM_SECTIONS];
01991         int awcNSS[NUM_SECTIONS];
01992         int wcSthArmor = 0;
01993         int wcNSS = 0;
01994         int wcAngel = 0;
01995         int cl = MechSpecials(mech) & CLAN_TECH;
01996         int e_count = 0;
01997         int tTechOK = 1;
01998         int wcHvyFF = 0;
01999         int wcLtFF = 0;
02000         int wcC3i = 0;
02001         int wcBloodhound = 0;
02002         int awInfSpec[5];
02003         int wcSuits = 0;
02004 
02005         MechSpecials(mech) &=
02006                 ~(BEAGLE_PROBE_TECH | TRIPLE_MYOMER_TECH | MASC_TECH | ECM_TECH |
02007                   C3_SLAVE_TECH | C3_MASTER_TECH | ARTEMIS_IV_TECH | ES_TECH |
02008                   FF_TECH | IS_ANTI_MISSILE_TECH | CL_ANTI_MISSILE_TECH);
02009         if(MechType(mech) == CLASS_MECH)
02010                 MechSpecials(mech) &= ~(XL_TECH | XXL_TECH | CE_TECH | LE_TECH);
02011 
02012         MechSpecials2(mech) &=
02013                 ~(STEALTH_ARMOR_TECH | NULLSIGSYS_TECH | ANGEL_ECM_TECH |
02014                   HVY_FF_ARMOR_TECH | LT_FF_ARMOR_TECH | TAG_TECH | C3I_TECH |
02015                   BLOODHOUND_PROBE_TECH | TCOMP_TECH);
02016 
02017         MechInfantrySpecials(mech) &=
02018                 ~(CS_PURIFIER_STEALTH_TECH | DC_KAGE_STEALTH_TECH |
02019                   FWL_ACHILEUS_STEALTH_TECH | FC_INFILTRATOR_STEALTH_TECH |
02020                   FC_INFILTRATORII_STEALTH_TECH);
02021 
02022         for(x = 0; x < 5; x++)
02023                 awInfSpec[x] = 0;
02024 
02025         for(x = 0; x < NUM_SECTIONS; x++) {
02026                 e_count = 0;
02027                 MechSections(mech)[x].config &= ~CASE_TECH;
02028                 awcSthArmor[x] = 0;
02029                 awcNSS[x] = 0;
02030 
02031                 for(y = 0; y < CritsInLoc(mech, x); y++)
02032                         if((t = GetPartType(mech, x, y))) {
02033                                 switch (Special2I(t)) {
02034 #define TECHC(item,name) case item: name++; break;
02035 #define TECHCU(item,name) \
02036                                 case item: if (!PartIsNonfunctional(mech, x, y)) name++; break;
02037 #define TECH(item,name) case item: MechSpecials(mech) |= name; break
02038 #define TECH2(item,name) case item: MechSpecials2(mech) |= name; break
02039 #define TECHU(item, name) \
02040                                 case item: if (!PartIsNonfunctional(mech, x, y)) MechSpecials(mech) |= name ; break
02041                                         TECH(ARTEMIS_IV, ARTEMIS_IV_TECH);
02042                                         TECHU(BEAGLE_PROBE, BEAGLE_PROBE_TECH);
02043                                         TECH(ECM, ECM_TECH);
02044                                         TECH2(TAG, TAG_TECH);
02045                                         TECHU(C3_SLAVE, C3_SLAVE_TECH);
02046                                         TECHCU(MASC, masc_count);
02047                                         TECHC(C3_MASTER, c3_master_count);
02048                                         TECHCU(C3I, wcC3i);
02049                                         TECHCU(ANGELECM, wcAngel);
02050                                         TECHC(TRIPLE_STRENGTH_MYOMER, tsm_count);
02051                                         TECHC(FERRO_FIBROUS, ff_count);
02052                                         TECHC(HVY_FERRO_FIBROUS, wcHvyFF);
02053                                         TECHC(LT_FERRO_FIBROUS, wcLtFF);
02054                                         TECHC(BLOODHOUND_PROBE, wcBloodhound);
02055                                         TECHCU(TARGETING_COMPUTER, tc_count);
02056                                         TECHC(ENDO_STEEL, es_count);
02057                                         TECHC(PURIFIER_ARMOR, awInfSpec[0]);
02058                                         TECHCU(KAGE_STEALTH_UNIT, awInfSpec[1]);
02059                                         TECHCU(ACHILEUS_STEALTH_UNIT, awInfSpec[2]);
02060                                         TECHCU(INFILTRATOR_STEALTH_UNIT, awInfSpec[3]);
02061                                         TECHCU(INFILTRATORII_STEALTH_UNIT, awInfSpec[4]);
02062                                 case ENGINE:
02063                                         e_count++;
02064                                         break;
02065                                 case CASE:
02066                                         MechSections(mech)[(MechType(mech) == CLASS_VEH_GROUND)
02067                                                                            ? BSIDE : x].config |= CASE_TECH;
02068                                         break;
02069                                 case STEALTH_ARMOR:
02070                                         awcSthArmor[x]++;
02071                                         wcSthArmor++;
02072                                         break;
02073                                 case NULL_SIGNATURE_SYSTEM:
02074                                         awcNSS[x]++;
02075                                         wcNSS++;
02076                                         break;
02077                                 }
02078                                 if(IsWeapon(t) && IsAMS(Weapon2I(t))) {
02079                                         if(MechWeapons[Weapon2I(t)].special & CLAT)
02080                                                 MechSpecials(mech) |= CL_ANTI_MISSILE_TECH;
02081                                         else
02082                                                 MechSpecials(mech) |= IS_ANTI_MISSILE_TECH;
02083                                 }
02084                         }
02085                 if(x != CTORSO && e_count) {
02086                         if(e_count > 3)
02087                                 MechSpecials(mech) |= XXL_TECH;
02088 
02089                         else if(e_count == 2)
02090                                 if(cl)
02091                                         MechSpecials(mech) |= XL_TECH;
02092 
02093                                 else
02094                                         MechSpecials(mech) |= LE_TECH;
02095 
02096                         else
02097                                 MechSpecials(mech) |= XL_TECH;
02098                 } else {
02099                         if(x == CTORSO && e_count < 4 && MechType(mech) == CLASS_MECH)
02100                                 MechSpecials(mech) |= CE_TECH;
02101                 }
02102 
02103         }
02104         if((MechSpecials(mech) & (XXL_TECH | XL_TECH | LE_TECH)) &&
02105            (MechSpecials(mech) & CE_TECH))
02106                 SendError(tprintf
02107                                   ("#%d apparently is very weird: Compact engine AND XL/XXL?",
02108                                    mech->mynum));
02109         if(tc_count) {
02110                 MechSpecials2(mech) |= TCOMP_TECH;
02111                 for(x = 0; x < NUM_SECTIONS; x++)
02112                         for(y = 0; y < CritsInLoc(mech, x); y++)
02113                                 if(IsWeapon((t = GetPartType(mech, x, y))))
02114                                         if(TCAble(t))
02115                                                 GetPartFireMode(mech, x, y) |= ON_TC;
02116         }
02117         if(masc_count >= MAX(1, (MechTons(mech) / (cl ? 25 : 20))))
02118                 MechSpecials(mech) |= MASC_TECH;
02119 #define ITech(var,cnt,spec) \
02120   if (((var)) >= ((cnt)) || (MechType(mech) != CLASS_MECH && ((var)>0))) \
02121                                         MechSpecials(mech) |= spec
02122 
02123 #define ITech2(var,cnt,spec) \
02124   if (((var)) >= ((cnt)) || (MechType(mech) != CLASS_MECH && ((var)>0))) \
02125                                         MechSpecials2(mech) |= spec
02126 
02127         ITech(ff_count, (cl ? 7 : 14), FF_TECH);
02128         ITech(es_count, (cl ? 7 : 14), ES_TECH);
02129         ITech(tsm_count, 6, TRIPLE_MYOMER_TECH);
02130         ITech2(wcAngel, 2, ANGEL_ECM_TECH);
02131         ITech2(wcHvyFF, 21, HVY_FF_ARMOR_TECH);
02132         ITech2(wcLtFF, 7, LT_FF_ARMOR_TECH);
02133         ITech2(wcC3i, 2, C3I_TECH);
02134         ITech2(wcBloodhound, 2, BLOODHOUND_PROBE_TECH);
02135 
02136         /*
02137          * Check our NSS. Need 1 crit in each loc except H
02138          */
02139         tTechOK = 0;
02140 
02141         if(wcNSS > 0) {
02142                 tTechOK = 1;
02143 
02144                 if(MechType(mech) != CLASS_MECH) {
02145                         if(wcNSS < 1)
02146                                 tTechOK = 0;
02147                 } else {
02148                         for(x = 0; x < NUM_SECTIONS; x++) {
02149                                 if(x != HEAD) {
02150                                         if(awcNSS[x] < 1) {
02151                                                 tTechOK = 0;
02152                                                 break;
02153                                         }
02154                                 }
02155                         }
02156                 }
02157 
02158                 if(tTechOK)
02159                         MechSpecials2(mech) |= NULLSIGSYS_TECH;
02160         }
02161 
02162         /*
02163          * Check our Stealth armor. Need 2 crits in each loc except H and CT
02164          */
02165         tTechOK = 0;
02166 
02167         if(wcSthArmor > 0) {
02168                 tTechOK = 1;
02169 
02170                 if(!(MechSpecials(mech) & ECM_TECH)) {
02171                         tTechOK = 0;
02172                 } else {
02173                         if(MechType(mech) != CLASS_MECH) {
02174                                 if(wcSthArmor < 1)
02175                                         tTechOK = 0;
02176                         } else {
02177                                 for(x = 0; x < NUM_SECTIONS; x++) {
02178                                         if((x != HEAD) && (x != CTORSO)) {
02179                                                 if(awcSthArmor[x] < 2) {
02180                                                         tTechOK = 0;
02181                                                         break;
02182                                                 }
02183                                         }
02184                                 }
02185                         }
02186                 }
02187 
02188                 if(tTechOK)
02189                         MechSpecials2(mech) |= STEALTH_ARMOR_TECH;
02190         }
02191 
02192         /* Let's do our suit checks */
02193         if(MechType(mech) == CLASS_BSUIT) {
02194                 wcSuits = CountBSuitMembers(mech);
02195 
02196                 if(awInfSpec[0] >= wcSuits)
02197                         MechInfantrySpecials(mech) |= CS_PURIFIER_STEALTH_TECH;
02198 
02199                 if(awInfSpec[1] >= wcSuits)
02200                         MechInfantrySpecials(mech) |= DC_KAGE_STEALTH_TECH;
02201 
02202                 if(awInfSpec[2] >= wcSuits)
02203                         MechInfantrySpecials(mech) |= FWL_ACHILEUS_STEALTH_TECH;
02204 
02205                 if(awInfSpec[3] >= wcSuits)
02206                         MechInfantrySpecials(mech) |= FC_INFILTRATOR_STEALTH_TECH;
02207 
02208                 if(awInfSpec[4] >= wcSuits)
02209                         MechInfantrySpecials(mech) |= FC_INFILTRATORII_STEALTH_TECH;
02210         }
02211 
02212         /* New C3 Master code */
02213         if(c3_master_count > 0) {
02214                 MechTotalC3Masters(mech) = countTotalC3MastersOnMech(mech);
02215                 MechWorkingC3Masters(mech) = countWorkingC3MastersOnMech(mech);
02216 
02217                 if(MechTotalC3Masters(mech) > 0)
02218                         MechSpecials(mech) |= C3_MASTER_TECH;
02219 
02220                 if(MechWorkingC3Masters(mech) == 0)
02221                         MechCritStatus(mech) |= C3_DESTROYED;
02222                 else
02223                         MechCritStatus(mech) &= ~C3_DESTROYED;
02224         }
02225 }
02226 
02227 int update_oweight(MECH * mech, int value)
02228 {
02229         MechCritStatus(mech) |= OWEIGHT_OK;
02230 
02231         /* Check to prevent silliness */
02232         if(!mudconf.btech_dynspeed || (value == 1 && !Destroyed(mech)))
02233                 value = MechTons(mech) * 1024;
02234         MechRTonsV(mech) = value;
02235         return value;
02236 }
02237 
02238 int get_weight(MECH * mech)
02239 {
02240         if(MechCritStatus(mech) & OWEIGHT_OK)
02241                 return MechRTonsV(mech);
02242         return update_oweight(mech, mech_weight_sub(GOD, mech, -1));
02243 }
02244 
02245 int load_template(dbref player, MECH * mech, char *filename)
02246 {
02247         char line[MAX_STRING_LENGTH], buf[MAX_STRING_LENGTH];
02248         int x, y, value, i;
02249         char cmd[MAX_STRING_LENGTH];
02250         char *ptr, *j, *k, *line2;
02251         int section = 0, critical, selection, type, brand;
02252         FILE *fp = fopen(filename, "r");
02253         char *tmpc;
02254         int lpos, hpos;
02255         int ok_count = 0;
02256         int isClan = 0;
02257         int t;
02258         int wFireModes, wAmmoModes;
02259         MAP *map;
02260 
02261         if(!fp)
02262                 return -1;
02263 
02264         ptr = strrchr(filename, '/');
02265         if(ptr == NULL) {
02266                 ptr = filename;
02267         } else {
02268                 ptr++;
02269         }
02270         strncpy(MechType_Ref(mech), ptr, 15);
02271         MechType_Ref(mech)[14] = '\0';
02272 
02273         silly_atr_set(mech->mynum, A_MECHREF, MechType_Ref(mech));
02274         MechRadioType(mech) = 0;
02275         while (fgets(line, 512, fp)) {
02276                 line[strlen(line) - 1] = '\0';
02277                 j = line;
02278                 while (isspace(*j))
02279                         j++;
02280                 if(j != line)
02281                         memmove(line, j, strlen(j) + 1);
02282                 if((ptr = strchr(line, ' '))) {
02283                         if((tmpc = strchr(line, '\t')) < ptr)
02284                                 if(tmpc)
02285                                         ptr = tmpc;
02286                         j = line;
02287                         k = cmd;
02288                         while (j != ptr)
02289                                 *(k++) = *(j++);
02290                         *k = 0;
02291                         for(ptr++; isspace(*ptr); ptr++);
02292                 } else {
02293                         strcpy(cmd, line);
02294                         strcpy(line, "");
02295                         ptr = NULL;
02296                 }
02297                 if(!strncasecmp(cmd, "CRIT_", 5))
02298                         selection = 9999;
02299                 else if((selection = compare_array(load_cmds, cmd)) == -1) {
02300                         /* Initial premise: we will have a mech type before we get to this */
02301                         section = find_section(cmd, MechType(mech), MechMove(mech));
02302                         TEMPLATE_ERR(section == -1 &&
02303                                                  !ok_count,
02304                                                  "New template loading system: %s is invalid template file.",
02305                                                  filename);
02306                         TEMPLATE_GERR(section == -1,
02307                                                   "Error while loading: Section %s not found.", cmd);
02308                         MechSections(mech)[section].recycle = 0;
02309                         ok_count++;
02310                         continue;
02311                 }
02312                 ok_count++;
02313                 switch (selection) {
02314                 case 0:                         /* Reference */
02315                         tmpc = read_desc(fp, ptr);
02316                         if(strcmp(tmpc, MechType_Ref(mech))) {
02317                                 SendError(tprintf
02318                                                   ("Template %s has Reference <-> Filename mismatch : %s <-> %s - It is automatically fixed by saving again.",
02319                                                    filename, tmpc, MechType_Ref(mech)));
02320                                 tmpc = MechType_Ref(mech);
02321                         }
02322                         silly_atr_set(mech->mynum, A_MECHREF, tmpc);
02323                         strcpy(MechType_Ref(mech), tmpc);
02324                         break;
02325                 case 1:                         /* Type */
02326                         tmpc = read_desc(fp, ptr);
02327                         MechType(mech) = compare_array(mech_types, tmpc);
02328                         TEMPLATE_GERR(MechType(mech) == -1,
02329                                                   "Error while loading: Type %s not found.", tmpc);
02330                         AeroFuel(mech) = AeroFuelOrig(mech) = DefaultFuelByType(mech);
02331                         break;
02332                 case 2:                         /* Movement Type */
02333                         tmpc = read_desc(fp, ptr);
02334                         MechMove(mech) = compare_array(move_types, tmpc);
02335                         TEMPLATE_GERR(MechMove(mech) == -1,
02336                                                   "Error while loading: Type %s not found.", tmpc);
02337                         break;
02338                 case 3:                         /* Tons */
02339                         MechTons(mech) = atoi(read_desc(fp, ptr));
02340                         break;
02341                 case 4:                         /* Tac_Range */
02342                         MechTacRange(mech) = atoi(read_desc(fp, ptr));
02343                         break;
02344                 case 5:                         /* LRS_Range */
02345                         MechLRSRange(mech) = atoi(read_desc(fp, ptr));
02346                         break;
02347                 case 6:                         /* Radio Range */
02348                         MechRadioRange(mech) = atoi(read_desc(fp, ptr));
02349                         break;
02350                 case 7:                         /* Scan Range */
02351                         MechScanRange(mech) = atoi(read_desc(fp, ptr));
02352                         break;
02353                 case 8:                         /* Heat Sinks */
02354                         MechRealNumsinks(mech) = atoi(read_desc(fp, ptr));
02355                         break;
02356                 case 9:                         /* Max Speed */
02357                         SetMaxSpeed(mech, atof(read_desc(fp, ptr)));
02358                         TemplateMaxSpeed(mech) = MechMaxSpeed(mech);
02359                         break;
02360                 case 10:                                /* Specials */
02361                         tmpc = read_desc(fp, ptr);
02362 
02363                         if(CheckSpecialsList(specials, specials2, tmpc)) {
02364                                 MechSpecials(mech) |= BuildBitVectorNoErr(specials, tmpc);
02365                                 MechSpecials2(mech) |= BuildBitVectorNoErr(specials2, tmpc);
02366                         } else
02367                                 TEMPLATE_GERR(MechSpecials(mech) == -1,
02368                                                           "Error while loading: Invalid specials - %s.",
02369                                                           tmpc);
02370                         break;
02371                 case 11:                                /* Armor */
02372                         SetSectOArmor(mech, section, atoi(read_desc(fp, ptr)));
02373                         SetSectArmor(mech, section, GetSectOArmor(mech, section));
02374                         break;
02375                 case 12:                                /* Internals */
02376                         SetSectOInt(mech, section, atoi(read_desc(fp, ptr)));
02377                         SetSectInt(mech, section, GetSectOInt(mech, section));
02378                         break;
02379                 case 13:                                /* Rear */
02380                         SetSectORArmor(mech, section, atoi(read_desc(fp, ptr)));
02381                         SetSectRArmor(mech, section, GetSectORArmor(mech, section));
02382                         break;
02383                 case 14:                                /* Config */
02384                         tmpc = read_desc(fp, ptr);
02385                         MechSections(mech)[section].config =
02386                                 BuildBitVector(section_configs,
02387                                                            tmpc) & ~(CASE_TECH | SECTION_DESTROYED);
02388                         TEMPLATE_GERR(MechSections(mech)[section].config == -1,
02389                                                   "Error while loading: Invalid location config: %s.",
02390                                                   tmpc);
02391                         break;
02392                 case 9999:
02393                         if((sscanf(cmd, "CRIT_%d-%d", &x, &y)) == 2) {
02394                                 lpos = x - 1;
02395                                 hpos = y - 1;
02396                         } else if((sscanf(cmd, "CRIT_%d", &x)) == 1) {
02397                                 lpos = x - 1;
02398                                 hpos = x - 1;
02399                         } else
02400                                 break;
02401                         critical = lpos;
02402                         line2 = read_desc(fp, ptr);
02403                         line2 = one_arg(line2, buf);
02404                         if(!strncasecmp(buf, "CL.", 3))
02405                                 isClan = 1;
02406                         TEMPLATE_GERR(!(find_matching_vlong_part(buf, NULL, &type,
02407                                                                                                          &brand)),
02408                                                   "Unable to find %s", buf);
02409                         SetPartType(mech, section, critical, type);
02410                         if(!mudconf.btech_parts)
02411                                 brand = 0;
02412                         SetPartBrand(mech, section, critical, brand);
02413                         SetPartDesiredAmmoLoc(mech, section, critical, -1);
02414 
02415                         if(IsWeapon(type)) {
02416                                 /* Thanks to legacy of past, we _do_ have to do this.. sniff */
02417                                 if(IsAMS(Weapon2I(type))) {
02418                                         if(MechWeapons[Weapon2I(type)].special & CLAT)
02419                                                 MechSpecials(mech) |= CL_ANTI_MISSILE_TECH;
02420                                         else
02421                                                 MechSpecials(mech) |= IS_ANTI_MISSILE_TECH;
02422                                 }
02423                                 SetPartData(mech, section, critical, 0);
02424                                 line2 = one_arg(line2, buf);    /* Don't need the '-' */
02425                                 line2 = one_arg(line2, buf);
02426 
02427 /*              wFireModes = BuildBitVector(crit_fire_modes, buf); */
02428 
02429 /*              wAmmoModes = BuildBitVector(crit_ammo_modes, buf); */
02430 
02431                                 wFireModes = BuildBitVectorWithDelim(crit_fire_modes, buf);
02432                                 wAmmoModes = BuildBitVectorWithDelim(crit_ammo_modes, buf);
02433 
02434                                 TEMPLATE_GERR(((wFireModes < 0) && (wAmmoModes < 0)),
02435                                                           "Error while loading: Invalid crit modes for weapon: %s.",
02436                                                           buf);
02437 
02438                                 if(wFireModes < 0)
02439                                         wFireModes = 0;
02440 
02441                                 if(wAmmoModes < 0)
02442                                         wAmmoModes = 0;
02443 
02444                                 GetPartFireMode(mech, section, critical) = wFireModes;
02445                                 GetPartAmmoMode(mech, section, critical) = wAmmoModes;
02446 
02447                                 line2 = one_arg(line2, buf);
02448                                 if(mudconf.btech_parts)
02449                                         if(atoi(buf)) {
02450                                                 SetPartBrand(mech, section, critical, atoi(buf));
02451                                         }
02452                         } else if(IsAmmo(type)) {
02453                                 line2 = one_arg(line2, buf);
02454                                 GetPartData(mech, section, critical) = atoi(buf);
02455                                 line2 = one_arg(line2, buf);
02456 
02457 /*              wFireModes = BuildBitVector(crit_fire_modes, buf); */
02458 
02459 /*              wAmmoModes = BuildBitVector(crit_ammo_modes, buf); */
02460 
02461                                 wFireModes = BuildBitVectorWithDelim(crit_fire_modes, buf);
02462                                 wAmmoModes = BuildBitVectorWithDelim(crit_ammo_modes, buf);
02463 
02464                                 TEMPLATE_GERR(((wFireModes < 0) && (wAmmoModes < 0)),
02465                                                           "Error while loading: Invalid crit modes for ammo: %s.",
02466                                                           buf);
02467 
02468                                 if(wFireModes < 0)
02469                                         wFireModes = 0;
02470 
02471                                 if(wAmmoModes < 0)
02472                                         wAmmoModes = 0;
02473 
02474                                 GetPartFireMode(mech, section, critical) = wFireModes;
02475                                 GetPartAmmoMode(mech, section, critical) = wAmmoModes;
02476 
02477                                 if(GetPartData(mech, section, critical) < FullAmmo(mech,
02478                                                                                                                                    section,
02479                                                                                                                                    critical))
02480                                 {
02481                                         GetPartFireMode(mech, section, critical) |= HALFTON_MODE;
02482                                         if(GetPartData(mech, section,
02483                                                                    critical) > FullAmmo(mech, section,
02484                                                                                                                 critical))
02485                                                 GetPartFireMode(mech, section, critical) &=
02486                                                         ~HALFTON_MODE;
02487                                 }
02488 
02489                                 if(GetPartData(mech, section, critical) != FullAmmo(mech,
02490                                                                                                                                         section,
02491                                                                                                                                         critical)
02492                                    && MechType(mech) != CLASS_MW
02493                                    && MechType(mech) != CLASS_BSUIT) {
02494                                         SendError(tprintf
02495                                                           ("Invalid ammo crit for %s in #%d %s (%d/%d)",
02496                                                            MechWeapons[Ammo2I(type)].name, mech->mynum,
02497                                                            filename, GetPartData(mech, section, critical),
02498                                                            FullAmmo(mech, section, critical))
02499                                                 );
02500                                         SetPartData(mech, section, critical, FullAmmo(mech,
02501                                                                                                                                   section,
02502                                                                                                                                   critical));
02503                                 }
02504                         } else {
02505                                 GetPartData(mech, section, critical) = 0;
02506                                 GetPartFireMode(mech, section, critical) = 0;
02507                                 GetPartAmmoMode(mech, section, critical) = 0;
02508                                 if((line2 = one_arg(line2, buf)))
02509                                         if((line2 = one_arg(line2, buf))) {
02510                                                 line2 = one_arg(line2, buf);
02511                                                 if(mudconf.btech_parts)
02512                                                         if(atoi(buf)) {
02513                                                                 SetPartBrand(mech, section, critical,
02514                                                                                          atoi(buf));
02515                                                         }
02516                                         }
02517                         }
02518                         for(x = (lpos + 1); x <= hpos; x++) {
02519                                 SetPartType(mech, section, x, GetPartType(mech, section,
02520                                                                                                                   lpos));
02521                                 SetPartData(mech, section, x, GetPartData(mech, section,
02522                                                                                                                   lpos));
02523                                 SetPartFireMode(mech, section, x, GetPartFireMode(mech,
02524                                                                                                                                   section,
02525                                                                                                                                   lpos));
02526                                 SetPartAmmoMode(mech, section, x,
02527                                                                 GetPartAmmoMode(mech, section, lpos));
02528                                 SetPartBrand(mech, section, x,
02529                                                          GetPartBrand(mech, section, lpos));
02530                         }
02531                         break;
02532                 case 15:                                /* Mech's Computer level */
02533                         MechComputer(mech) = atoi(read_desc(fp, ptr));
02534                         break;
02535                 case 16:                                /* Name of the mech */
02536                         strcpy(MechType_Name(mech), read_desc(fp, ptr));
02537                         break;
02538                 case 17:                                /* Jj's */
02539                         MechJumpSpeed(mech) = atof(read_desc(fp, ptr));
02540                         break;
02541                 case 18:                                /* Radio */
02542                         MechRadio(mech) = atoi(read_desc(fp, ptr));
02543                         break;
02544                 case 19:                                /* SI */
02545                         AeroSI(mech) = AeroSIOrig(mech) = atoi(read_desc(fp, ptr));
02546                         break;
02547                 case 20:                                /* Fuel */
02548                         AeroFuel(mech) = AeroFuelOrig(mech) = atoi(read_desc(fp, ptr));
02549                         break;
02550                 case 21:                                /* Comment */
02551                         break;
02552                 case 22:                                /* Radio_freqs */
02553                         MechRadioType(mech) = atoi(read_desc(fp, ptr));
02554                         break;
02555                 case 23:                                /* Mech battle value */
02556                         MechBV(mech) = atoi(read_desc(fp, ptr));
02557                         break;
02558                 case 24:                                /* Cargospace */
02559                         CargoSpace(mech) = atoi(read_desc(fp, ptr));
02560                         break;
02561                 case 25:                                /* Maxsuits */
02562                         MechMaxSuits(mech) = atoi(read_desc(fp, ptr));
02563                         break;
02564                 case 26:                                /* Specials */
02565                         tmpc = read_desc(fp, ptr);
02566 
02567                         if(CheckSpecialsList(infantry_specials, 0, tmpc))
02568                                 MechInfantrySpecials(mech) |=
02569                                         BuildBitVectorNoErr(infantry_specials, tmpc);
02570 
02571                         break;
02572                 case 27:                                /* Carmaxton */
02573                         CarMaxTon(mech) = atoi(read_desc(fp, ptr));
02574                         break;
02575                 }
02576         }
02577         fclose(fp);
02578         MechEngineSizeV(mech) = MechEngineSizeC(mech);
02579 #define Set(a,b) \
02580                 if (!(a)) a = b
02581         if(!(MechSpecials(mech) & ICE_TECH))
02582                 Set(MechRealNumsinks(mech), DEFAULT_HEATSINKS);
02583         if(MechType(mech) == CLASS_MECH)
02584                 do_sub_magic(mech, 1);
02585         if(MechType(mech) == CLASS_MW)
02586                 Startup(mech);
02587 
02588         if(MechType(mech) == CLASS_MECH)
02589                 value = 8;
02590         else
02591                 value = 6;
02592 
02593         if(mudconf.btech_parts)
02594                 for(x = 0; x < value; x++)
02595                         for(y = 0; y < CritsInLoc(mech, x); y++)
02596                                 if((t = GetPartType(mech, x, y))) {
02597                                         if(GetPartBrand(mech, x, y))
02598                                                 continue;
02599                                         if(IsAmmo(t))
02600                                                 continue;
02601                                         if(IsBomb(t))
02602                                                 continue;
02603                                         SetPartBrand(mech, x, y,
02604                                                                  isClan ? DEFAULT_CLPART_LEVEL :
02605                                                                  DEFAULT_PART_LEVEL);
02606                                 }
02607         if(isClan) {
02608                 Set(MechComputer(mech), DEFAULT_CLCOMPUTER);
02609                 Set(MechRadio(mech), DEFAULT_CLRADIO);
02610         } else {
02611                 Set(MechComputer(mech), DEFAULT_COMPUTER);
02612                 Set(MechRadio(mech), DEFAULT_RADIO);
02613         }
02614         if(!MechRadioType(mech))
02615                 MechRadioType(mech) = generic_radio_type(MechRadio(mech), isClan);
02616         if(!MechComputer(mech)) {
02617                 Set(MechScanRange(mech), DEFAULT_SCANRANGE);
02618                 Set(MechLRSRange(mech), DEFAULT_LRSRANGE);
02619                 Set(MechRadioRange(mech), DEFAULT_RADIORANGE);
02620                 Set(MechTacRange(mech), DEFAULT_TACRANGE);
02621         } else {
02622                 Set(MechScanRange(mech), MechComputersScanRange(mech));
02623                 Set(MechLRSRange(mech), MechComputersLRSRange(mech));
02624                 Set(MechRadioRange(mech), MechComputersRadioRange(mech));
02625                 Set(MechTacRange(mech), MechComputersTacRange(mech));
02626         }
02627 #if 1                                                   /* Don't know if we're ready for this yet - aw, what the hell :) */
02628         if(MechType(mech) == CLASS_MECH)
02629                 if((GetPartType(mech, LARM, 2) != Special(LOWER_ACTUATOR)) &&
02630                    (GetPartType(mech, RARM, 2) != Special(LOWER_ACTUATOR)) &&
02631                    (GetPartType(mech, LARM, 3) != Special(HAND_OR_FOOT_ACTUATOR))
02632                    && (GetPartType(mech, RARM, 3) != Special(HAND_OR_FOOT_ACTUATOR)))
02633                         MechSpecials(mech) |= FLIPABLE_ARMS;
02634 #endif
02635         update_specials(mech);
02636         MechXPMod(mech) = 1.0; /* Default it to 1 (no mod effect at all) */
02637         mech_int_check(mech, 1);
02638         x = mech_weight_sub(GOD, mech, 0);
02639         y = MechTons(mech) * 1024;
02640         if(abs(x - y) > 40)
02641                 SendError(tprintf
02642                                   ("Error in %s template: %.1f tons of 'stuff', yet %d ton frame.",
02643                                    MechType_Ref(mech), x / 1024.0, y / 1024));
02644         update_oweight(mech, x);
02645         if((map = FindObjectsData(mech->mapindex)))
02646                 UpdateConditions(mech, map);
02647         /* To prevent certain funny occurences.. */
02648         for(i = 0; i < NUM_SECTIONS; i++)
02649                 if(!(GetSectOInt(mech, i)))
02650                         SetSectDestroyed(mech, i);
02651         return 0;
02652 }
02653 
02654 void DumpMechSpecialObjects(dbref player)
02655 {
02656         coolmenu *c;
02657 
02658         c = AutoCol_StringMenu("MechSpecials available", internals);
02659         ShowCoolMenu(player, c);
02660         KillCoolMenu(c);
02661 }
02662 
02663 static char *dumpweapon_fun(int i)
02664 {
02665         static char buf[256];
02666 
02667         buf[0] = 0;
02668         if(!i)
02669                 sprintf(buf, WDUMP_MASKS);
02670         else {
02671                 i--;
02672                 sprintf(buf, WDUMP_MASK, MechWeapons[i].name, MechWeapons[i].heat,
02673                                 MechWeapons[i].damage, MechWeapons[i].min,
02674                                 MechWeapons[i].shortrange, MechWeapons[i].medrange,
02675                                 GunRange(i), MechWeapons[i].vrt, MechWeapons[i].criticals,
02676                                 MechWeapons[i].ammoperton);
02677         }
02678         return buf;
02679 }
02680 
02681 void DumpWeapons(dbref player)
02682 {
02683         coolmenu *c;
02684 
02685         c = SelCol_FunStringMenuK(1, "MechWeapons available", dumpweapon_fun,
02686                                                           num_def_weapons + 1);
02687         ShowCoolMenu(player, c);
02688         KillCoolMenu(c);
02689 }
02690 
02691 char *techlist_func(MECH * mech)
02692 {
02693         static char buffer[MBUF_SIZE];
02694         char bufa[SBUF_SIZE], bufb[SBUF_SIZE];
02695         int i, ii, part = 0, axe = 0, mace = 0, sword = 0, saw = 0, hascase = 0;
02696 
02697         snprintf(bufa, SBUF_SIZE, "%s",
02698                          BuildBitString(specialsabrev, MechSpecials(mech)));
02699         snprintf(bufb, SBUF_SIZE, "%s",
02700                          BuildBitString(specialsabrev2, MechSpecials2(mech)));
02701         snprintf(buffer, MBUF_SIZE, "%s %s", bufa, bufb);
02702 
02703         if(!
02704            (strstr(buffer, "XL") || strstr(buffer, "XXL")
02705                 || strstr(buffer, "LENG") || strstr(buffer, "ICE")
02706                 || strstr(buffer, "CENG")))
02707                 strcat(buffer, " FUS ");
02708         for(i = 0; i < NUM_SECTIONS; i++)
02709                 for(ii = 0; ii < NUM_CRITICALS; ii++) {
02710                         part = GetPartType(mech, i, ii);
02711                         if(part == I2Special(AXE) && !axe) {
02712                                 axe = 1;
02713                                 strcat(buffer, " AXE");
02714                         }
02715                         if(part == I2Special(MACE) && !mace) {
02716                                 mace = 1;
02717                                 strcat(buffer, " MACE");
02718                         }
02719                         if(part == I2Special(DUAL_SAW) && !saw) {
02720                                 saw = 1;
02721                                 strcat(buffer, " DUAL_SAW");
02722                         }
02723                         if(part == I2Special(SWORD) && !sword) {
02724                                 sword = 1;
02725                                 strcat(buffer, " SWORD");
02726                         }
02727                         if((MechSections(mech)[i].config & CASE_TECH) && !hascase) {
02728                                 hascase = 1;
02729                                 strcat(buffer, " CASE");
02730                         }
02731                 }
02732 
02733         if(CargoSpace(mech))
02734                 strcat(buffer, " INFC");
02735 
02736         if(MechType(mech) == CLASS_VTOL)
02737                 strcat(buffer, " VTOL");
02738 
02739         if(MechType(mech) == CLASS_MECH && MechMove(mech) != MOVE_QUAD) {
02740                 if((OkayCritSectS(RARM, 3, HAND_OR_FOOT_ACTUATOR)
02741                         && OkayCritSectS(RARM, 0, SHOULDER_OR_HIP))
02742                    || (OkayCritSectS(LARM, 3, HAND_OR_FOOT_ACTUATOR)
02743                            && OkayCritSectS(LARM, 0, SHOULDER_OR_HIP))
02744                    || MechSpecials(mech) & SALVAGE_TECH)
02745                         strcat(buffer, " MTOW");
02746         } else {
02747                 if(MechSpecials(mech) & SALVAGE_TECH)
02748                         strcat(buffer, " MTOW");
02749         }
02750 
02751         return buffer;
02752 }
02753 
02754 /* Function to return the payload of a unit
02755  * Used by the btpayload_ref() scode function
02756  * Dany - 06/2005 */
02757 char *payloadlist_func(MECH * mech)
02758 {
02759         static char buffer[MBUF_SIZE];
02760 
02761         unsigned char weaparray[MAX_WEAPS_SECTION];
02762         unsigned char weapdata[MAX_WEAPS_SECTION];
02763         int critical[MAX_WEAPS_SECTION];
02764         short ammomode;
02765         int temp_crit;
02766 
02767         int count, weap_count, ammo_count, section_loop, weap_loop, put_loop;
02768         char payloadbuff[120];
02769 
02770         unsigned short payload_items[8 * MAX_WEAPS_SECTION];
02771         unsigned short payload_items_count[8 * MAX_WEAPS_SECTION];
02772 
02773         /* Clear the buffer */
02774         snprintf(buffer, MBUF_SIZE, "%s", "");
02775 
02776         /* Count each 'unique' item */
02777         weap_count = 0;
02778         ammo_count = 0;
02779 
02780         /* Initialize array */
02781         for(put_loop = 0; put_loop < 8 * MAX_WEAPS_SECTION; put_loop++) {
02782                 payload_items[put_loop] = 0;
02783                 payload_items_count[put_loop] = 0;
02784         }
02785 
02786         /* Get the weapons for each sections */
02787         for(section_loop = 0; section_loop < NUM_SECTIONS; section_loop++) {
02788 
02789                 /* Get all the weapons for that section */
02790                 count =
02791                         FindWeapons(mech, section_loop, weaparray, weapdata, critical);
02792                 /* Check if any weapons in that section */
02793                 if(count <= 0)
02794                         continue;
02795 
02796                 /* Loop through all the weapons found and store their values */
02797                 for(weap_loop = 0; weap_loop < count; weap_loop++) {
02798 
02799                         /* Loop to put weapons in the temp array and keep count */
02800                         for(put_loop = 0; put_loop < 8 * MAX_WEAPS_SECTION; put_loop++) {
02801 
02802                                 /* Check to see if there is already an entry */
02803                                 if(payload_items[put_loop] == weaparray[weap_loop]) {
02804                                         payload_items_count[put_loop]++;
02805                                         break;
02806                                         /* Ok, see if there is no entry */
02807                                 } else if(payload_items[put_loop] == 0) {
02808                                         payload_items[put_loop] = weaparray[weap_loop];
02809                                         payload_items_count[put_loop]++;
02810                                         weap_count++;
02811                                         break;
02812                                 }
02813 
02814                         }                                       /* End of put loop */
02815 
02816                 }                                               /* End of weap count loop */
02817 
02818         }                                                       /* End of section loop */
02819 
02820         /* Loop through all the sections */
02821         for(section_loop = 0; section_loop < NUM_SECTIONS; section_loop++) {
02822 
02823                 /* Loop through all the crits in a section */
02824                 for(count = 0; count < MAX_WEAPS_SECTION; count++) {
02825 
02826                         /* Get the Part at that spot */
02827                         temp_crit = GetPartType(mech, section_loop, count);
02828 
02829                         /* Is it Ammo? */
02830                         if(IsAmmo(temp_crit)) {
02831 
02832                                 /* Loop to put weapons in the temp array and keep count */
02833                                 for(put_loop = weap_count; put_loop < 8 * MAX_WEAPS_SECTION;
02834                                         put_loop++) {
02835 
02836                                         /* Check to see if there is already an entry */
02837                                         if(payload_items[put_loop] == temp_crit) {
02838                                                 payload_items_count[put_loop]++;
02839                                                 break;
02840                                                 /* Ok, see if there is no entry */
02841                                         } else if(payload_items[put_loop] == 0) {
02842                                                 payload_items[put_loop] = temp_crit;
02843                                                 payload_items_count[put_loop]++;
02844                                                 ammo_count++;
02845                                                 break;
02846                                         }
02847 
02848                                 }                               /* End of put loop */
02849 
02850                         }
02851                         /* End of is it Ammo if Statement */
02852                 }                                               /* End of Crit Slot Loop */
02853 
02854         }                                                       /* End of Section Loop */
02855 
02856         /* Final loop to print out the full payload to the buffer and return it */
02857         for(put_loop = 0; put_loop < (weap_count + ammo_count); put_loop++) {
02858 
02859                 /* If its a weapon use this method of printing it out
02860                  * Else use the part method */
02861                 if(put_loop < weap_count) {
02862                         sprintf(payloadbuff, "%s:%d",
02863                                         &MechWeapons[payload_items[put_loop]].name[0],
02864                                         payload_items_count[put_loop]);
02865                 } else {
02866                         sprintf(payloadbuff, "%s:%d",
02867                                         partname_func(payload_items[put_loop], 'V'),
02868                                         payload_items_count[put_loop]);
02869                 }
02870 
02871                 /* If we are not at the end, then put a | as a spacer */
02872                 if(put_loop < (weap_count + ammo_count - 1)) {
02873                         strncat(payloadbuff, "|", sizeof(buffer) - strlen(buffer) - 1);
02874                 }
02875 
02876                 /* Adding it to the main buffer */
02877                 strncat(buffer, payloadbuff, sizeof(buffer) - strlen(buffer) - 1);
02878 
02879         }                                                       /* End of printing loop */
02880 
02881         return buffer;
02882 }

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