📄 scenarioloader.java
字号:
/* * MegaMek - Copyright (C) 2003, 2004, 2005 Ben Mazur (bmazur@sev.org) * ScenarioLoader - Copyright (C) 2002 Josh Yockey * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */package megamek.server;import java.util.*;import megamek.common.*;import java.io.File;import java.io.FileInputStream;import megamek.common.loaders.*;import megamek.common.options.IOption;import megamek.common.util.BoardUtilities;public class ScenarioLoader { private File m_scenFile; // copied from ChatLounge.java private Vector m_vDamagePlans = new Vector(); //Used to store Crit Hits private Vector m_vCritHitPlans = new Vector(); //Used to set ammo Spec Ammounts private Vector m_vSetAmmoTo = new Vector(); public ScenarioLoader(File f) { m_scenFile = f; } /** * The damage procedures are built into a server object, so we delay * dealing the random damage until a server is made available to us. */ public void applyDamage(Server s) { for (int x = 0, n = m_vDamagePlans.size(); x < n; x++) { DamagePlan dp = (DamagePlan)m_vDamagePlans.elementAt(x); System.out.println( "Applying damage to " + dp.entity.getShortName() ); for (int y = 0; y < dp.nBlocks; y++) { HitData hit = dp.entity.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT); System.out.println("[s.damageEntity(dp.entity, hit, 5)]"); s.damageEntity(dp.entity, hit, 5); } //Apply Spec Dammage for ( int dpspot = 0, dpcount = dp.specificDammage.size(); dpspot < dpcount; dpspot++ ) { //Get the SpecDam SpecDam sd = ((SpecDam)dp.specificDammage.elementAt(dpspot)); if (dp.entity.locations() <= sd.loc) //Make sure the the location is valid System.out.println("\tInvalid Location Specified " + sd.loc); else { //Infantry only take dammage to "internal" if (sd.internal || ((dp.entity instanceof Infantry ) && !(dp.entity instanceof BattleArmor ))) { if (dp.entity.getOInternal(sd.loc) > sd.setArmorTo) { dp.entity.setInternal(sd.setArmorTo,sd.loc); System.out.println("\tSet Armor Value for (Internal " + dp.entity.getLocationName(sd.loc) + ") To " + sd.setArmorTo); if (sd.setArmorTo == 0) { //Mark destroy if internal armor is set to zero System.out.println("\tSection Destoyed " + dp.entity.getLocationName(sd.loc)); s.destroyLocation(dp.entity,sd.loc); } } } else { if (sd.rear && dp.entity.hasRearArmor(sd.loc)) { if (dp.entity.getOArmor(sd.loc,true) > sd.setArmorTo) { System.out.println("\tSet Armor Value for (Rear " + dp.entity.getLocationName(sd.loc) + ") To " + sd.setArmorTo); dp.entity.setArmor(sd.setArmorTo,sd.loc,true); } } else { if (dp.entity.getOArmor(sd.loc,false) > sd.setArmorTo) { System.out.println("\tSet Armor Value for (" + dp.entity.getLocationName(sd.loc) + ") To " + sd.setArmorTo); //Battle Armor Handled Differently //If armor set to Zero kill the Armor sport which represents //one member of the squad if (dp.entity instanceof BattleArmor ) { if (sd.setArmorTo ==0 ) { dp.entity.setArmor(IArmorState.ARMOR_DOOMED, sd.loc, false); dp.entity.setInternal(IArmorState.ARMOR_DOOMED, sd.loc); } else { //For some reason setting armor to 1 will result in 2 armor points //left on the GUI Dont know why but adjust here! dp.entity.setArmor(sd.setArmorTo-1,sd.loc); } } else { dp.entity.setArmor(sd.setArmorTo,sd.loc); } } } } } } } //Loop throught Crit Hits for (int chSpot = 0, chCount = m_vCritHitPlans.size(); chSpot < chCount; chSpot++) { CritHitPlan chp = (CritHitPlan)m_vCritHitPlans.elementAt(chSpot); System.out.print("Applying Critical Hits to " + chp.entity.getShortName()); for (int chpspot = 0, chpcount = chp.critHits.size();chpspot < chpcount; chpspot++) { //Get the ScritHit CritHit ch = ((CritHit)chp.critHits.elementAt(chpspot)); // Apply a critical hit to the indicated slot. if (chp.entity.locations() <= ch.loc) System.out.println("\n\tInvalid Location Specified " + ch.loc); else { // Make sure that we have crit spot to hit if ( chp.entity instanceof Mech || chp.entity instanceof Protomech ) { // Is this a torso weapon slot? CriticalSlot cs = null; if ( chp.entity instanceof Protomech && Protomech.LOC_TORSO == ch.loc && ( Protomech.SYSTEM_TORSO_WEAPON_A == ch.slot || Protomech.SYSTEM_TORSO_WEAPON_B == ch.slot ) ) { cs = new CriticalSlot ( CriticalSlot.TYPE_SYSTEM, ch.slot ); } // Is this a valid slot number? else if ( ch.slot < 0 || ch.slot > chp.entity.getNumberOfCriticals(ch.loc) ) { System.out.println ( "\n\tInvalid Slot Specified " + ch.loc + ":" + (ch.slot+1) ); } // Get the slot from the entity. else { cs = chp.entity.getCritical(ch.loc, ch.slot); } // Ignore invalid, unhittable, and damaged slots. if ( null == cs || !cs.isHittable() ) { System.out.println ( "\n\tSlot not hittable " + ch.loc + ":" + (ch.slot+1) ); } else { System.out.print( "[s.applyCriticalHit(chp.entity, ch.loc, cs, false)]" ); s.applyCriticalHit(chp.entity, ch.loc, cs, false); } } // Handle Tanks differently. else if (chp.entity instanceof Tank) { if ( ch.slot < 0 || ch.slot >= 6 ) { System.out.println ( "\n\tInvalid Slot Specified " + ch.loc + ":" + (ch.slot+1) ); } else { CriticalSlot cs = new CriticalSlot ( CriticalSlot.TYPE_SYSTEM, ch.slot+1 ); System.out.print( "[s.applyCriticalHit(chp.entity, ch.loc, cs, false)]" ); s.applyCriticalHit(chp.entity, Entity.NONE, cs, false); } } // End have-tank } // End have-valid-location } // Handle the next critical hit // Print a line between hit plans. System.out.println(); } // Handle the next critical hit plan //Loop throught Set Ammo To for (int saSpot = 0, saCount = m_vSetAmmoTo.size(); saSpot < saCount; saSpot++) { SetAmmoPlan sap = (SetAmmoPlan)m_vSetAmmoTo.elementAt(saSpot); System.out.println("Applying Ammo Adjustment to " + sap.entity.getShortName()); for (int sapSpot = 0, sapCount = sap.ammoSetTo.size();sapSpot < sapCount; sapSpot++) { //Get the ScritHit SetAmmoTo sa = ((SetAmmoTo)sap.ammoSetTo.elementAt(sapSpot)); //Only can be done against Mechs if (sap.entity instanceof Mech ) { if (sa.slot < sap.entity.getNumberOfCriticals(sa.loc)) { //Get the piece of Eqipment and Check to make sure it is //a ammo item then set its amount! CriticalSlot cs = sap.entity.getCritical(sa.loc, sa.slot); if (!(cs == null)) { Mounted ammo = sap.entity.getEquipment(sap.entity.getCritical(sa.loc, sa.slot).getIndex()); if (ammo.getType() instanceof AmmoType ) { //Also make sure we dont exceed the max aloud ammo.setShotsLeft(Math.min(sa.setAmmoTo,ammo.getShotsLeft())); } } } } } } } public IGame createGame() throws Exception { System.out.println("Loading scenario from " + m_scenFile); Properties p = loadProperties(); String sCheck = p.getProperty("MMSVersion"); if (sCheck == null) { throw new Exception("Not a valid MMS file. No MMSVersion."); } Game g = new Game(); // build the board g.board = createBoard(p); // build the faction players Player[] players = createPlayers(p); for (int x = 0; x < players.length; x++) { g.addPlayer(x, players[x]); } // build the entities int nIndex = 0; for (int x = 0; x < players.length; x++) { Entity[] entities = buildFactionEntities(p, players[x]); for (int y = 0; y < entities.length; y++) { entities[y].setOwner(players[x]); entities[y].setId(nIndex++); g.addEntity(entities[y].getId(), entities[y]); } } // game's ready g.getOptions().initialize(); String optionFile = p.getProperty("GameOptionsFile"); if(optionFile == null) { g.getOptions().loadOptions(); } else { g.getOptions().loadOptions(new File(m_scenFile.getParentFile(), optionFile)); } // set wind g.determineWind(); // Set up the teams (for initiative) g.setupTeams(); g.setPhase(IGame.PHASE_STARTING_SCENARIO); g.setupRoundDeployment(); return g; } private Entity[] buildFactionEntities(Properties p, Player player) throws Exception { String sFaction = player.getName(); Vector vEntities = new Vector(); for (int i = 1; true; i++) { String s = p.getProperty("Unit_" + sFaction + "_" + i); if (s == null) { // prepare and return array Entity[] out = new Entity[vEntities.size()]; vEntities.copyInto(out); return out; } Entity e = parseEntityLine(s); //Damage Plan Stuff boolean dpCreated = false; DamagePlan dp = new DamagePlan(e); s = p.getProperty("Unit_" + sFaction + "_" + i + "_Damage"); if (s != null) { int nBlocks = Integer.parseInt(s); m_vDamagePlans.addElement(new DamagePlan(e, nBlocks)); } //Add the Specif Dammage if it exists s = p.getProperty("Unit_" + sFaction + "_" + i + "_DamageSpecific"); if (s != null) { StringTokenizer st = new StringTokenizer(s,","); while (st.hasMoreTokens()) { dp.AddSpecificDammage(st.nextToken()); } dpCreated = true; } //Add Crit Hits if it exists boolean chpCreated = false; s = p.getProperty("Unit_" + sFaction + "_" + i + "_CritHit"); CritHitPlan chp = new CritHitPlan(e); if (s != null) { StringTokenizer st = new StringTokenizer(s,","); while (st.hasMoreTokens()) { chp.AddCritHit(st.nextToken()); } chpCreated = true; } //Add Set Ammo Locations boolean sapCreated = false; s = p.getProperty("Unit_" + sFaction + "_" + i + "_SetAmmoTo"); SetAmmoPlan sap = new SetAmmoPlan(e); if (s != null) { StringTokenizer st = new StringTokenizer(s,","); while (st.hasMoreTokens()) { sap.AddSetAmmoTo(st.nextToken()); } sapCreated = true; } if (chpCreated) m_vCritHitPlans.addElement(chp); if (dpCreated) m_vDamagePlans.addElement(dp); if (sapCreated) m_vSetAmmoTo.addElement(sap); //Check for advantages s = p.getProperty("Unit_" + sFaction + "_" + i + "_Advantages"); if ( null != s ) { parseAdvantages(e, s); } //Check for autoeject s = p.getProperty("Unit_" + sFaction + "_" + i + "_AutoEject"); if ( null != s) { parseAutoEject(e, s); } //Check for deployment s = p.getProperty("Unit_" + sFaction + "_" + i + "_DeploymentRound"); if ( null != s ) { int round = 0; try { round = Integer.parseInt(s); } catch ( Exception ex ) { throw new Exception("Bad deployment round setting (" + s + ") for unit " + sFaction + ":" + i); } if ( round < 0 ) { System.out.println("Deployment round setting of '" + round + "' for " + sFaction + ":" + i + " will be ignored and set to 0"); round = 0; } if ( round > 0 ) { if ( player.getStartingPos() == 0 ) { throw new Exception("Can not combine a starting position of 'any' with delayed deployment."); } System.out.println(e.getDisplayName() + " will be deployed before round " + round); e.setDeployRound(round); } } vEntities.addElement(e); } } private Entity parseEntityLine(String s) throws Exception { try { StringTokenizer st = new StringTokenizer(s, ","); String sRef = st.nextToken(); MechSummary ms = MechSummaryCache.getInstance().getMech(sRef); if (ms == null) { throw new Exception("Scenario requires missing entity: " + sRef); } System.out.println("Loading " + ms.getName()); Entity e = new MechFileParser(ms.getSourceFile(), ms.getEntryName()).getEntity(); e.setCrew(new Pilot(st.nextToken(), Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()))); try { String direction = st.nextToken(); if (direction.equalsIgnoreCase("N")) { e.setFacing(0); } else if (direction.equalsIgnoreCase("NW")) { e.setFacing(5); } else if (direction.equalsIgnoreCase("SW")) { e.setFacing(4); } else if (direction.equalsIgnoreCase("S")) { e.setFacing(3); } else if (direction.equalsIgnoreCase("SE")) { e.setFacing(2); } else if (direction.equalsIgnoreCase("NE")) { e.setFacing(1); } int x = Integer.parseInt(st.nextToken())-1; int y = Integer.parseInt(st.nextToken())-1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -