package com.planet_ink.coffee_mud.Commands; import com.planet_ink.coffee_mud.core.interfaces.*; import com.planet_ink.coffee_mud.core.*; import com.planet_ink.coffee_mud.Abilities.interfaces.*; import com.planet_ink.coffee_mud.Areas.interfaces.*; import com.planet_ink.coffee_mud.Behaviors.interfaces.*; import com.planet_ink.coffee_mud.CharClasses.interfaces.*; import com.planet_ink.coffee_mud.Commands.interfaces.*; import com.planet_ink.coffee_mud.Common.interfaces.*; import com.planet_ink.coffee_mud.Exits.interfaces.*; import com.planet_ink.coffee_mud.Items.interfaces.*; import com.planet_ink.coffee_mud.Locales.interfaces.*; import com.planet_ink.coffee_mud.MOBS.interfaces.*; import com.planet_ink.coffee_mud.Races.interfaces.*; import java.util.*; /* Copyright 2000-2010 Bo Zimmerman Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ @SuppressWarnings("unchecked") public class CharGen extends StdCommand { public CharGen(){} private String[] access={"CHARGEN"}; public String[] getAccessWords(){return access;} protected void equipPlayer(MOB M) { int level = M.baseEnvStats().level(); CharClass C=M.baseCharStats().getCurrentClass(); for(int pos=0;pos<Item.WORN_CODES.length;pos++) { long wornCode=Item.WORN_CODES[pos]; if((wornCode == Item.IN_INVENTORY) || (wornCode == Item.WORN_HELD) || (wornCode == Item.WORN_MOUTH)) continue; if(wornCode==Item.WORN_WIELD) { Weapon W=CMClass.getWeapon("GenWeapon"); W.setWeaponClassification(Weapon.CLASS_SWORD); W.setWeaponType(Weapon.TYPE_SLASHING); W.setMaterial(RawMaterial.RESOURCE_STEEL); W.setRawProperLocationBitmap(Item.WORN_WIELD|Item.WORN_HELD); W.setRawLogicalAnd(true); switch(C.allowedWeaponLevel()) { case CharClass.WEAPONS_EVILCLERIC: CMLib.factions().setAlignment(M,Faction.ALIGN_EVIL); case CharClass.WEAPONS_THIEFLIKE: case CharClass.WEAPONS_BURGLAR: case CharClass.WEAPONS_ANY: case CharClass.WEAPONS_NEUTRALCLERIC: break; case CharClass.WEAPONS_DAGGERONLY: W.setWeaponClassification(Weapon.CLASS_DAGGER); W.setWeaponType(Weapon.TYPE_PIERCING); break; case CharClass.WEAPONS_NATURAL: W.setMaterial(RawMaterial.RESOURCE_OAK); break; case CharClass.WEAPONS_ROCKY: W.setMaterial(RawMaterial.RESOURCE_STONE); break; case CharClass.WEAPONS_GOODCLERIC: CMLib.factions().setAlignment(M,Faction.ALIGN_GOOD); case CharClass.WEAPONS_MAGELIKE: W.setMaterial(RawMaterial.RESOURCE_OAK); W.setWeaponClassification(Weapon.CLASS_STAFF); W.setWeaponType(Weapon.TYPE_BASHING); break; case CharClass.WEAPONS_ALLCLERIC: if(CMLib.flags().isGood(M)) { W.setMaterial(RawMaterial.RESOURCE_OAK); W.setWeaponClassification(Weapon.CLASS_STAFF); W.setWeaponType(Weapon.TYPE_BASHING); } break; case CharClass.WEAPONS_FLAILONLY: W.setWeaponClassification(Weapon.CLASS_FLAILED); W.setWeaponType(Weapon.TYPE_BASHING); break; } W.baseEnvStats().setLevel(level); W.baseEnvStats().setWeight(8); W.recoverEnvStats(); CMLib.itemBuilder().balanceItemByLevel(W); M.addInventory(W); W.wearIfPossible(M); } else if(wornCode != Item.WORN_FLOATING_NEARBY) { Armor A=CMClass.getArmor("GenArmor"); A.setRawProperLocationBitmap(wornCode); A.setMaterial(RawMaterial.RESOURCE_STEEL); if((CharClass.ARMOR_WEARMASK & wornCode) > 0) switch(C.allowedArmorLevel()) { case CharClass.ARMOR_ANY: case CharClass.ARMOR_METALONLY: break; case CharClass.ARMOR_CLOTH: A.setMaterial(RawMaterial.RESOURCE_COTTON); break; case CharClass.ARMOR_LEATHER: A.setMaterial(RawMaterial.RESOURCE_LEATHER); break; case CharClass.ARMOR_NONMETAL: case CharClass.ARMOR_VEGAN: case CharClass.ARMOR_OREONLY: A.setMaterial(RawMaterial.RESOURCE_OAK); break; } A.baseEnvStats().setLevel(level); A.baseEnvStats().setWeight(8); A.recoverEnvStats(); CMLib.itemBuilder().balanceItemByLevel(A); M.addInventory(A); A.wearIfPossible(M); } } } protected MOB levelMOBup(int level, CharClass C) { MOB mob=CMClass.getMOB("StdMOB"); CMLib.factions().setAlignment(mob,Faction.ALIGN_NEUTRAL); mob.setName("Average Joe"); mob.baseCharStats().setMyRace(CMClass.getRace("Human")); mob.baseCharStats().setStat(CharStats.STAT_GENDER,'M'); mob.baseCharStats().setStat(CharStats.STAT_STRENGTH,11); mob.baseCharStats().setStat(CharStats.STAT_WISDOM,11); mob.baseCharStats().setStat(CharStats.STAT_INTELLIGENCE,10); mob.baseCharStats().setStat(CharStats.STAT_DEXTERITY,11); mob.baseCharStats().setStat(CharStats.STAT_CONSTITUTION,10); mob.baseCharStats().setStat(CharStats.STAT_CHARISMA,10); mob.baseCharStats().setCurrentClass(C); mob.baseCharStats().setClassLevel(C,1); mob.baseEnvStats().setArmor(100); mob.baseEnvStats().setLevel(1); mob.baseEnvStats().setSensesMask(0); mob.baseState().setHitPoints(20); mob.baseState().setMovement(100); mob.baseState().setMana(100); mob.baseCharStats().getMyRace().startRacing(mob,false); mob.recoverCharStats(); mob.recoverEnvStats(); mob.recoverMaxState(); mob.baseCharStats().getCurrentClass().startCharacter(mob,false,false); int max=CMProps.getIntVar(CMProps.SYSTEMI_BASEMAXSTAT); for(int lvl=1;lvl<level;lvl++) { if((lvl % 3)==0) { int stat=-1; int bestDiff=0; for(int i=0;i<CharStats.NUM_BASE_STATS;i++) { int base = max + mob.charStats().getStat(CharStats.STAT_MAX_STRENGTH_ADJ + i); int diff = base - mob.baseCharStats().getStat(i); if(diff >= bestDiff) { stat=i; bestDiff = diff; } } if(stat>=0) if(mob.baseCharStats().getStat(stat)<(max+mob.charStats().getStat(CharStats.STAT_MAX_STRENGTH_ADJ + stat))) mob.baseCharStats().setStat(stat,mob.baseCharStats().getStat(stat)+1); } if(mob.getExpNeededLevel()==Integer.MAX_VALUE) CMLib.leveler().level(mob); else CMLib.leveler().postExperience(mob,null,null,mob.getExpNeededLevel()+1,false); mob.recoverEnvStats(); mob.recoverCharStats(); mob.recoverMaxState(); } equipPlayer(mob); for(int a=0;a<mob.numAbilities();a++) mob.fetchAbility(a).setProficiency(100); for(int a=0;a<mob.numEffects();a++) mob.fetchEffect(a).setProficiency(100); mob.recoverCharStats(); mob.recoverEnvStats(); mob.recoverMaxState(); mob.resetToMaxState(); return mob; } public void averageout(MOB avgMob, int tries) { avgMob.baseCharStats().setStat(CharStats.STAT_STRENGTH,(int)Math.round(CMath.div(avgMob.baseCharStats().getStat(CharStats.STAT_STRENGTH),tries))); avgMob.baseCharStats().setStat(CharStats.STAT_WISDOM,(int)Math.round(CMath.div(avgMob.baseCharStats().getStat(CharStats.STAT_WISDOM),tries))); avgMob.baseCharStats().setStat(CharStats.STAT_INTELLIGENCE,(int)Math.round(CMath.div(avgMob.baseCharStats().getStat(CharStats.STAT_INTELLIGENCE),tries))); avgMob.baseCharStats().setStat(CharStats.STAT_DEXTERITY,(int)Math.round(CMath.div(avgMob.baseCharStats().getStat(CharStats.STAT_DEXTERITY),tries))); avgMob.baseCharStats().setStat(CharStats.STAT_CONSTITUTION,(int)Math.round(CMath.div(avgMob.baseCharStats().getStat(CharStats.STAT_CONSTITUTION),tries))); avgMob.baseCharStats().setStat(CharStats.STAT_CHARISMA,(int)Math.round(CMath.div(avgMob.baseCharStats().getStat(CharStats.STAT_CHARISMA),tries))); avgMob.baseEnvStats().setArmor((int)Math.round(CMath.div(avgMob.baseEnvStats().armor(),tries))); avgMob.baseState().setHitPoints((int)Math.round(CMath.div(avgMob.baseState().getHitPoints(),tries))); avgMob.baseState().setMovement((int)Math.round(CMath.div(avgMob.baseState().getMovement(),tries))); avgMob.baseState().setMana((int)Math.round(CMath.div(avgMob.baseState().getMana(),tries))); avgMob.recoverCharStats(); avgMob.recoverEnvStats(); avgMob.recoverMaxState(); avgMob.resetToMaxState(); avgMob.setTrains(0); } public void addHimIn(MOB avgMob, MOB mob2) { avgMob.baseCharStats().setStat(CharStats.STAT_STRENGTH,avgMob.baseCharStats().getStat(CharStats.STAT_STRENGTH)+mob2.baseCharStats().getStat(CharStats.STAT_STRENGTH)); avgMob.baseCharStats().setStat(CharStats.STAT_WISDOM,avgMob.baseCharStats().getStat(CharStats.STAT_WISDOM)+mob2.baseCharStats().getStat(CharStats.STAT_WISDOM)); avgMob.baseCharStats().setStat(CharStats.STAT_INTELLIGENCE,avgMob.baseCharStats().getStat(CharStats.STAT_INTELLIGENCE)+mob2.baseCharStats().getStat(CharStats.STAT_INTELLIGENCE)); avgMob.baseCharStats().setStat(CharStats.STAT_DEXTERITY,avgMob.baseCharStats().getStat(CharStats.STAT_DEXTERITY)+mob2.baseCharStats().getStat(CharStats.STAT_DEXTERITY)); avgMob.baseCharStats().setStat(CharStats.STAT_CONSTITUTION,avgMob.baseCharStats().getStat(CharStats.STAT_CONSTITUTION)+mob2.baseCharStats().getStat(CharStats.STAT_CONSTITUTION)); avgMob.baseCharStats().setStat(CharStats.STAT_CHARISMA,avgMob.baseCharStats().getStat(CharStats.STAT_CHARISMA)+mob2.baseCharStats().getStat(CharStats.STAT_CHARISMA)); avgMob.baseEnvStats().setArmor(avgMob.baseEnvStats().armor()+mob2.baseEnvStats().armor()); avgMob.baseState().setHitPoints(avgMob.baseState().getHitPoints()+mob2.baseState().getHitPoints()); avgMob.baseState().setMovement(avgMob.baseState().getMovement()+mob2.baseState().getMovement()); avgMob.baseState().setMana(avgMob.baseState().getMana()+mob2.baseState().getMana()); avgMob.recoverCharStats(); avgMob.recoverEnvStats(); avgMob.recoverMaxState(); avgMob.resetToMaxState(); } public MOB AverageClassMOB(MOB mob, int level, CharClass C, int numTries) { MOB avgMob=levelMOBup(level,C); int tries=0; for(;tries<numTries;tries++) { if(((tries % 20)==0)&&(mob!=null)) mob.session().print("."); MOB mob2=levelMOBup(level,C); addHimIn(avgMob,mob2); } averageout(avgMob,tries+1); return avgMob; } public MOB AverageAllClassMOB(MOB mob, int level, int numTriesClass, int numTriesMOB) { MOB avgMob=null; int tries=0; int numClasses=0; for(;tries<numTriesClass;tries++) { for(Enumeration c=CMClass.charClasses();c.hasMoreElements();) { CharClass C=(CharClass)c.nextElement(); if(C.availabilityCode()!=0) { numClasses++; MOB mob2=AverageClassMOB(mob,level,C,numTriesMOB); if(avgMob==null) { avgMob=mob2; numClasses--; } else addHimIn(avgMob,mob2); if(avgMob!=mob2) mob2.destroy(); } } } averageout(avgMob,numClasses); return avgMob; } private class CombatStats { int levelStart=1; int levelEnd=91; int TOTAL_ITERATIONS=100; int skipLevels=0; int[][][] allData=null;//new int[classSet.size()][levelEnd-levelStart+1][17]; String[][][] allSkills=null;//new String[classSet.size()][levelEnd-levelStart+1][4]; Area A=null; MOB mob=null; DVector classSet=new DVector(2); Hashtable failSkillCheck=null; } public void combatRun(MOB mob, Vector commands) { CombatStats c=new CombatStats(); c.mob=mob; if(commands.size()==0) { mob.tell("USAGE: CHARGEN COMBAT ([CHARCLASS(S)]...) (EXPORT=FILENAME) (FAILCHECK) (ITERATIONS=[X]) (SKIPLEVELS=[X]) ([START LEVEL]) ([END LEVEL])"); return; } String[][] CAMATCH={ {"Commoner","CombatAbilities"}, {"Bard","Bardness"}, {"Cleric","Clericness"}, {"Druid","Druidness"}, {"Mage","Mageness"}, {"Thief","Thiefness"}, {"Fighter","Fighterness"}, }; for(Enumeration e=CMClass.charClasses();e.hasMoreElements();) { CharClass C=(CharClass)e.nextElement(); if((CMath.bset(C.availabilityCode(),Area.THEME_FANTASY) ||CMath.bset(C.availabilityCode(),Area.THEME_HEROIC) ||CMath.bset(C.availabilityCode(),Area.THEME_TECHNOLOGY)) &&(!CMath.bset(C.availabilityCode(),Area.THEME_SKILLONLYMASK))) { String behav="CombatAbilities"; for(int x=0;x<CAMATCH.length;x++) if(C.baseClass().equalsIgnoreCase(CAMATCH[x][0])) behav=CAMATCH[x][1]; c.classSet.addElement(C,behav); } } // set the parameters boolean classCleared=false; boolean nextLevel=false; String fileExp=null; for(int i=0;i<commands.size();i++) { String s=(String)commands.elementAt(i); if(CMath.isInteger(s)) { int x=CMath.s_int(s); if(x>=0) { if((nextLevel)&&(x>=c.levelStart)) c.levelEnd=x; else if(!nextLevel) { c.levelStart=x; c.levelEnd=x; nextLevel=true; } } } else if(s.toUpperCase().startsWith("ITERATIONS=")) { s=s.substring("ITERATIONS=".length()); if(CMath.isInteger(s)) c.TOTAL_ITERATIONS=CMath.s_int(s); } else if(s.toUpperCase().startsWith("EXPORT=")) fileExp=s.substring("EXPORT=".length()); else if(s.toUpperCase().startsWith("SKIPLEVELS=")) { c.skipLevels=CMath.s_int(s.substring("SKIPLEVELS=".length())); if(c.skipLevels<1) c.skipLevels=1; } else if(CMClass.findCharClass(s)!=null) { CharClass C=CMClass.findCharClass(s); if(!classCleared) { classCleared=true; c.classSet=new DVector(2); } String behav="CombatAbilities"; for(int x=0;x<CAMATCH.length;x++) if(C.baseClass().equalsIgnoreCase(CAMATCH[x][0])) behav=CAMATCH[x][1]; c.classSet.addElement(C,behav); } else if(s.endsWith("s")) { s=s.substring(0,s.length()-1); for(Enumeration e=CMClass.charClasses();e.hasMoreElements();) { CharClass C=(CharClass)e.nextElement(); if((CMath.bset(C.availabilityCode(),Area.THEME_FANTASY) ||CMath.bset(C.availabilityCode(),Area.THEME_HEROIC) ||CMath.bset(C.availabilityCode(),Area.THEME_TECHNOLOGY)) &&(!CMath.bset(C.availabilityCode(),Area.THEME_SKILLONLYMASK)) &&(C.baseClass().equalsIgnoreCase(s)||(s.equalsIgnoreCase("charclasse")))) { if(!classCleared) { classCleared=true; c.classSet=new DVector(2); } String behav="CombatAbilities"; for(int x=0;x<CAMATCH.length;x++) if(C.baseClass().equalsIgnoreCase(CAMATCH[x][0])) behav=CAMATCH[x][1]; c.classSet.addElement(C,behav); } } } else if(s.equalsIgnoreCase("FAILCHECK")) c.failSkillCheck=new Hashtable(); } if(c.skipLevels<=0) { c.skipLevels=1; if((c.levelStart==1)&&(c.levelEnd==91)) c.skipLevels=15; } c.A=CMClass.getAreaType("StdArea"); c.A.setName("UNKNOWNAREA"); CMLib.map().addArea(c.A); c.allData=new int[c.classSet.size()][c.levelEnd-c.levelStart+1][17]; c.allSkills=new String[c.classSet.size()][c.levelEnd-c.levelStart+1][4]; final String[] allDataHeader={ "BestIterScore",//0 "BestHitScore",//1 "BestSingleHitScore",//2 "BestSingleHitPhys",//3 "Losses",//4 "MedScore",//5 "MedHitPct",//6 "LossIters",//7 "MedWinIters",//8 "MedPhysDone",//9 "MedPhysTaken",//10 "MedIsHitPct",//11 "LostRounds",//12 "PlayerArmor",//13 "PlayerAttack",//15 "PlayerDamPct",//16 "PlayerManaPct",//17 "BestIterSkill",//18 "BestHitSkill",//19 "BestSingleHitSkill",//20 }; boolean[] aborted = new boolean[1]; aborted[0]=false; final Random r = new Random(System.currentTimeMillis()); for(int charClassDex=0;charClassDex<c.classSet.size();charClassDex++) { java.util.concurrent.CountDownLatch latch = new java.util.concurrent.CountDownLatch(1); new Thread() { CombatStats c; int charClassDex; String fileExp; java.util.concurrent.CountDownLatch latch = null; boolean[] aborted; public void start(CombatStats c, int charClassDex, String fileExp, java.util.concurrent.CountDownLatch latch, boolean[] aborted){ this.c=c; this.charClassDex=charClassDex; this.fileExp=fileExp; this.latch=latch; this.aborted=aborted; this.start(); } public void run() { MOB mob=c.mob; int[][][] allData = c.allData; String[][][] allSkills=c.allSkills; DVector classSet=c.classSet; int levelStart=c.levelStart; for(int level=c.levelStart;level<=c.levelEnd;level+=c.skipLevels) { CharClass C=(CharClass)c.classSet.elementAt(charClassDex,1); mob.tell(C.ID()+": "+level); int roomRobin=0; Room R=null; int[] bestSingleHitScore=new int[]{0}; String[] bestSingleHitSkill=new String[]{""}; int[] bestSingleHitPhys=new int[]{0}; int[] bestHitScore=new int[]{0}; String[] bestHitSkill=new String[]{""}; int[] bestIterScore=new int[]{Integer.MAX_VALUE}; String[] bestIterSkill=new String[]{""}; int[] losses=new int[]{0}; Vector medScore=new Vector(); Vector medWinIters=new Vector(); Vector medPhysDone=new Vector(); Vector medHitPct=new Vector(); Vector medIsHitPct=new Vector(); Vector medPhysTaken=new Vector(); Vector medLossIters=new Vector(); Vector medPlayerDamPct = new Vector(); Vector medPlayerManaPct = new Vector(); int H1=0; int H2=0; boolean playerExampleShown=false; int lastPct=0; int playerArmor=0; int playerAttack=0; for(int tries=0;tries<c.TOTAL_ITERATIONS;tries++) { if((CMath.div(tries,c.TOTAL_ITERATIONS)*100.0)>=lastPct+5) { lastPct+=5; if(mob.session()!=null) mob.session().print("."); } Behavior B1=CMClass.getBehavior((String)classSet.elementAt(charClassDex,2)); B1.setParms(C.ID()); switch(roomRobin) { case 0: R=CMClass.getLocale("Woods"); break; case 1: R=CMClass.getLocale("CaveRoom"); break; case 2: R=CMClass.getLocale("CityStreet"); break; } if((++roomRobin)>2) roomRobin=0; if(R!=null) { R.addNonUninvokableEffect(CMClass.getAbility("Spell_Light")); R.setRoomID(c.A.name()+"#"+r.nextInt(Integer.MAX_VALUE)); R.setArea(c.A); R.recoverEnvStats(); } c.A.getTimeObj().setTimeOfDay(CMLib.dice().roll(1,c.A.getTimeObj().getHoursInDay(),-1)); //Session S=(Session)CMClass.getCommon("FakeSession"); //S.initializeSession(null,"MEMORY"); MOB M1=null; if(C.ID().equalsIgnoreCase("StdCharClass")) { M1=CMClass.getMOB("StdMOB"); // MOB stat Behavior B2=CMClass.getBehavior("CombatAbilities"); M1.baseCharStats().setMyRace(CMClass.getRace("Human")); M1.baseEnvStats().setLevel(level); M1.setName("GOODGUY"); M1.recoverCharStats(); M1.recoverEnvStats(); M1.setLocation(R); M1.baseCharStats().getMyRace().setHeightWeight(M1.baseEnvStats(),(char)M1.baseCharStats().getStat(CharStats.STAT_GENDER)); M1.baseEnvStats().setAbility(11); M1.recoverCharStats(); M1.recoverEnvStats(); M1.recoverMaxState(); M1.resetToMaxState(); M1.addBehavior(B2); M1.bringToLife(R,true); CMLib.threads().deleteTick(M1,Tickable.TICKID_MOB); CMLib.leveler().fillOutMOB(M1,level); //int hp=M1CMLib.leveler().getLevelMOBPlayerHP(M1); M1.setWimpHitPoint(0); M1.recoverMaxState(); M1.recoverCharStats(); M1.recoverEnvStats(); } else { M1=AverageClassMOB(null,level,C,1); M1.baseCharStats().setMyRace(CMClass.getRace("Human")); M1.setName("GOODGUY"); M1.recoverCharStats(); M1.recoverEnvStats(); M1.setLocation(R); M1.baseCharStats().getMyRace().setHeightWeight(M1.baseEnvStats(),(char)M1.baseCharStats().getStat(CharStats.STAT_GENDER)); M1.recoverCharStats(); M1.recoverEnvStats(); M1.recoverMaxState(); M1.resetToMaxState(); M1.bringToLife(M1.location(),true); CMLib.threads().deleteTick(M1,Tickable.TICKID_MOB); M1.setWimpHitPoint(0); M1.recoverMaxState(); M1.recoverCharStats(); M1.recoverEnvStats(); M1.resetToMaxState(); B1.setStat("PRECAST","1"); M1.addBehavior(B1); equipPlayer(M1); M1.recoverMaxState(); M1.recoverCharStats(); M1.recoverEnvStats(); B1.setStat("RECORD"," "); B1.setStat("PROF","true"); B1.setStat("LASTSPELL",""); B1.setStat("PRECAST","1"); for(int i=0;i<20;i++) // give some pre-cast ticks M1.tick(M1,Tickable.TICKID_MOB); } M1.resetToMaxState(); playerArmor=CMLib.combat().adjustedArmor(M1); playerAttack=CMLib.combat().adjustedAttackBonus(M1,null); MOB M2=CMClass.getMOB("StdMOB"); // MOB stat Behavior B2=CMClass.getBehavior("CombatAbilities"); M2.baseCharStats().setMyRace(CMClass.getRace("Human")); M2.baseEnvStats().setLevel(level); M2.setName("BADGUY"); M2.recoverCharStats(); M2.recoverEnvStats(); M2.setLocation(R); M2.baseCharStats().getMyRace().setHeightWeight(M2.baseEnvStats(),(char)M2.baseCharStats().getStat(CharStats.STAT_GENDER)); M2.baseEnvStats().setAbility(11); M2.recoverCharStats(); M2.recoverEnvStats(); M2.recoverMaxState(); M2.resetToMaxState(); M2.addBehavior(B2); M2.bringToLife(M2.location(),true); CMLib.threads().deleteTick(M2,Tickable.TICKID_MOB); CMLib.leveler().fillOutMOB(M2,level); int hp=CMLib.leveler().getPlayerHitPoints(M2); if(hp>M2.baseState().getHitPoints()) M2.baseState().setHitPoints(hp); M2.setWimpHitPoint(0); M2.recoverMaxState(); M2.recoverCharStats(); M2.recoverEnvStats(); M2.resetToMaxState(); M1.setVictim(M2); M2.setVictim(M1); if(!playerExampleShown) { playerExampleShown=true; /* StringBuffer msg=CMLib.commands().getScore(M1); if(!mob.isMonster()) mob.session().wraplessPrintln(msg.toString()); if(mob.session()!=null) { mob.session().println(M1.name()+" has "+B1.ID()+" behavior for "+M1.numAbilities()+" abilities."); mob.session().print("Working.."); } */ } H1=M1.curState().getHitPoints(); H2=M2.curState().getHitPoints(); int iterations=0; int cumScore=0; int hits = 0; int ishits = 0; B1.setStat("PHYSDAMTAKEN","0"); B2.setStat("PHYSDAMTAKEN","0"); int zeroCheck=0; //MOB[] ZEROMOBS=null; String ZEROSKILL1=null; String ZEROSKILL2=null; String ALMOSTZEROSKILL=null; int l1=0, l2=0; //chargen combat charclasses export=test.tab iterations=100 skiplevels=20 1 91 while((M1.getVictim()==M2) &&(M2.getVictim()==M1) &&(!M1.amDead()) &&(!M2.amDead()) &&(M1.location()==M2.location()) &&(iterations<1000)) { if(aborted[0]) { latch.countDown(); return; } iterations++; ALMOSTZEROSKILL=B1.getStat("LASTSPELL"); int h1=M1.curState().getHitPoints(); int h2=M2.curState().getHitPoints(); int L1=l1; int L2=l2; l1=CMath.s_int(B2.getStat("PHYSDAMTAKEN")); l2=CMath.s_int(B1.getStat("PHYSDAMTAKEN")); if(l1>L1) hits++; if(l2>L2) ishits++; try { CMLib.commands().postStand(M1,true); CMLib.commands().postStand(M2,true); M1.tick(M1,Tickable.TICKID_MOB); M2.tick(M2,Tickable.TICKID_MOB); } catch(Throwable t) { Log.errOut("CharGen",t); } int h=h2-(M2.amDead()?0:M2.curState().getHitPoints()); h=h-(h1-(M1.amDead()?0:M1.curState().getHitPoints())); if((h==0)&&((!M1.amDead())&&(!M2.amDead()))) { zeroCheck++; if(zeroCheck==1) { //ZEROMOBS=new MOB[]{(MOB)M1.copyOf(),(MOB)M2.copyOf()}; ZEROSKILL1=ALMOSTZEROSKILL; ZEROSKILL2=B1.getStat("LASTSPELL"); } else if(zeroCheck==20) Log.errOut("CharGen","Stale combat warning: "+ZEROSKILL1+"/"+ZEROSKILL2); else if(zeroCheck==100) { Log.errOut("CharGen","Stale Combat Abort: "+level+"/"+tries+"/"+iterations+"/"+ZEROSKILL1+"/"+ZEROSKILL2); //Log.errOut("CharGen",S.afkMessage()); break; } } else zeroCheck=0; if(h>bestSingleHitScore[0]) { bestSingleHitScore[0]=h; bestSingleHitPhys[0]=CMath.s_int(B2.getStat("PHYSDAMTAKEN"))-l1; bestSingleHitSkill[0]=B1.getStat("LASTSPELL"); } cumScore+=h; } if(iterations>=1000) Log.errOut("CharGen","Stale Combat Abort: "+level+"/"+tries+"/"+ZEROSKILL1+"/"+ZEROSKILL2); else if(M1.amDead()||M2.amDead()) { if(M1.amDead()) losses[0]++; medScore.addElement(Integer.valueOf(cumScore)); medPhysDone.addElement(Integer.valueOf(CMath.s_int(B2.getStat("PHYSDAMTAKEN")))); medPhysTaken.addElement(Integer.valueOf(CMath.s_int(B1.getStat("PHYSDAMTAKEN")))); medHitPct.addElement(Double.valueOf((CMath.div(hits,iterations)*100))); medIsHitPct.addElement(Double.valueOf((CMath.div(ishits,iterations)*100))); medPlayerDamPct.addElement(Double.valueOf(100-(CMath.div(M1.curState().getHitPoints(),H1)*100.0))); medPlayerManaPct.addElement(Double.valueOf(100-(CMath.div(M1.curState().getMana(),M1.maxState().getMana())*100.0))); if(M1.amDead()) medLossIters.addElement(Integer.valueOf(iterations)); else medWinIters.addElement(Integer.valueOf(iterations)); if(cumScore>bestHitScore[0]) { bestHitScore[0]=cumScore; bestHitSkill[0]=B1.getStat("RECORD"); } if(M2.amDead()) { if(!M1.amDead()) if(iterations<bestIterScore[0]) { bestIterScore[0]=iterations; bestIterSkill[0]=B1.getStat("RECORD"); } } if(c.failSkillCheck!=null) { Vector V=CMParms.parseSemicolons(B1.getStat("RECORD"),true); for(int v=0;v<V.size();v++) { String s=((String)V.elementAt(v)).trim(); boolean failed=false; if(s.startsWith("!")) { failed=true; s=s.substring(1); } int[] times=(int[])c.failSkillCheck.get(s); if(times==null) { times=new int[2]; c.failSkillCheck.put(s,times); } times[0]++; if(failed) times[1]++; } } } M1.destroy(); M2.destroy(); if(R!=null) { c.A.delProperRoom(R); R.destroy(); } } CMParms.sortVector(medScore); CMParms.sortVector(medHitPct); CMParms.sortVector(medLossIters); CMParms.sortVector(medWinIters); CMParms.sortVector(medPhysDone); CMParms.sortVector(medPhysTaken); CMParms.sortVector(medIsHitPct); CMParms.sortVector(medPlayerDamPct); CMParms.sortVector(medPlayerManaPct); allData[charClassDex][level-levelStart][0]=bestIterScore[0]; allData[charClassDex][level-levelStart][1]=bestHitScore[0]; allData[charClassDex][level-levelStart][2]=bestSingleHitScore[0]; allData[charClassDex][level-levelStart][3]=bestSingleHitPhys[0]; allData[charClassDex][level-levelStart][4]=losses[0]; if(medScore.size()>0) allData[charClassDex][level-levelStart][5]=((Integer)medScore.elementAt((int)Math.round(Math.floor(CMath.mul(0.5,medScore.size()))))).intValue(); if(medHitPct.size()>0) allData[charClassDex][level-levelStart][6]=((Double)medHitPct.elementAt((int)Math.round(Math.floor(CMath.mul(0.5,medHitPct.size()))))).intValue(); if(medLossIters.size()>0) allData[charClassDex][level-levelStart][7]=((Integer)medLossIters.elementAt((int)Math.round(Math.floor(CMath.mul(0.75,medLossIters.size()))))).intValue(); if(medWinIters.size()>0) allData[charClassDex][level-levelStart][8]=((Integer)medWinIters.elementAt((int)Math.round(Math.floor(CMath.mul(0.25,medWinIters.size()))))).intValue(); if(medPhysDone.size()>0) allData[charClassDex][level-levelStart][9]=((Integer)medPhysDone.elementAt((int)Math.round(Math.floor(CMath.mul(0.5,medPhysDone.size()))))).intValue(); if(medPhysTaken.size()>0) allData[charClassDex][level-levelStart][10]=((Integer)medPhysTaken.elementAt((int)Math.round(Math.floor(CMath.mul(0.5,medPhysTaken.size()))))).intValue(); if(medIsHitPct.size()>0) allData[charClassDex][level-levelStart][11]=((Double)medIsHitPct.elementAt((int)Math.round(Math.floor(CMath.mul(0.5,medIsHitPct.size()))))).intValue(); allData[charClassDex][level-levelStart][12]=losses[0]; allData[charClassDex][level-levelStart][13]=playerArmor; allData[charClassDex][level-levelStart][14]=playerAttack; if(medPlayerDamPct.size()>0) allData[charClassDex][level-levelStart][15]=((Double)medPlayerDamPct.elementAt((int)Math.round(Math.floor(CMath.mul(0.5,medPlayerDamPct.size()))))).intValue(); if(medPlayerManaPct.size()>0) allData[charClassDex][level-levelStart][16]=((Double)medPlayerManaPct.elementAt((int)Math.round(Math.floor(CMath.mul(0.5,medPlayerManaPct.size()))))).intValue(); allSkills[charClassDex][level-levelStart][0]=bestIterSkill[0]; allSkills[charClassDex][level-levelStart][1]=bestHitSkill[0]; allSkills[charClassDex][level-levelStart][2]=bestSingleHitSkill[0]; if(mob.session()!=null) mob.session().println("!"); if(fileExp==null) { mob.tell("HITPOINTS: "+H1+" vs "+H2); mob.tell("QUICKEST : "+bestIterScore[0]+": "+bestIterSkill[0]); mob.tell("MOST DAM : "+bestHitScore[0]+": "+bestHitSkill[0]); mob.tell("BEST HIT : "+bestSingleHitScore[0]+", Phys: "+bestSingleHitPhys[0]+", Skill: "+bestSingleHitSkill[0]); mob.tell("MEDIANS : HITS: "+allData[charClassDex][level-levelStart][5]+" ("+allData[charClassDex][level-levelStart][6]+"%), LOSS ITERS: "+allData[charClassDex][level-levelStart][7]+", WIN ITERS: "+allData[charClassDex][level-levelStart][8]); mob.tell("MEDIANS : PHYS DONE: "+allData[charClassDex][level-levelStart][9]+", PHYS TAKEN: "+allData[charClassDex][level-levelStart][10]+" ("+allData[charClassDex][level-levelStart][11]+"%)"); mob.tell("LOSSES : "+losses[0]); if((c.failSkillCheck!=null)&&(c.failSkillCheck.size()>0)) { StringBuffer fails=new StringBuffer("SKILLFAILS: "); for(Enumeration i=c.failSkillCheck.keys();i.hasMoreElements();) { String s=(String)i.nextElement(); int[] times=(int[])c.failSkillCheck.get(s); if(times[1]>0) { int pct=(int)Math.round(100.0*CMath.div(times[1],times[0])); if(pct>20) fails.append(s+"("+pct+"%) "); } } if(fileExp==null) mob.tell(fails.toString()); c.failSkillCheck.clear(); } } } latch.countDown(); } }.start(c,charClassDex,fileExp,latch,aborted); try { latch.await(); } catch(Exception e) { aborted[0]=true; return; } } mob.tell(""); if(fileExp!=null) { CMFile file=new CMFile(fileExp,mob,false); if(file.canWrite()) { StringBuffer buf=new StringBuffer(""); Vector baseClasses=new Vector(); for(int charClassDex=0;charClassDex<c.classSet.size();charClassDex++) { CharClass C=(CharClass)c.classSet.elementAt(charClassDex,1); if(!baseClasses.contains(C.baseClass())) baseClasses.addElement(C.baseClass()); } for(int d=0;d<c.allData[0][0].length;d++) { buf.append(allDataHeader[d]).append("\t\t"); for(int level=c.levelStart;level<=c.levelEnd;level+=c.skipLevels) buf.append(level).append('\t'); buf.append("\n\r"); for(int charClassDex=0;charClassDex<c.classSet.size();charClassDex++) { CharClass C=(CharClass)c.classSet.elementAt(charClassDex,1); buf.append(C.ID()).append("\t").append(C.baseClass()).append("\t"); for(int level=c.levelStart;level<=c.levelEnd;level+=c.skipLevels) { buf.append(c.allData[charClassDex][level-c.levelStart][d]).append('\t'); //for(int i=0;i<allSkills[charClassDex][level-levelStart].length;i++) // buf.append(allSkills[charClassDex][level-levelStart][i]).append('\t'); } buf.append("\n\r"); } buf.append("\n\r"); buf.append(allDataHeader[d]).append("\t*****\t"); for(int level=c.levelStart;level<=c.levelEnd;level+=c.skipLevels) buf.append(level).append('\t'); buf.append("\n\r"); for(int b=0;b<baseClasses.size();b++) { String baseClass=(String)baseClasses.elementAt(b); int[] levels=new int[c.levelEnd+1]; double ct=0; for(int charClassDex=0;charClassDex<c.classSet.size();charClassDex++) if(((CharClass)c.classSet.elementAt(charClassDex,1)).baseClass().equalsIgnoreCase(baseClass)) { ct+=1.0; for(int level=c.levelStart;level<=c.levelEnd;level+=c.skipLevels) levels[level]+=c.allData[charClassDex][level-c.levelStart][d]; } if(ct>0) { buf.append(baseClass).append("\t").append(baseClass).append("\t"); for(int level=c.levelStart;level<=c.levelEnd;level+=c.skipLevels) buf.append(Math.round(Integer.valueOf(levels[level]).doubleValue()/ct*100.0)/100).append('\t'); buf.append("\n\r"); } } buf.append("\n\r"); } file.saveText(buf); } } CMLib.map().delArea(c.A); c.A.destroy(); } public boolean execute(MOB mob, Vector commands, int metaFlags) throws java.io.IOException { if(mob.isMonster()) return false; commands.removeElementAt(0); boolean createNewOnly=false; if(commands.size()>0) { if(((String)commands.firstElement()).equalsIgnoreCase("COMBAT")) { commands.removeElementAt(0); combatRun(mob,commands); return true; } if(((String)commands.firstElement()).equalsIgnoreCase("NEW")) { commands.removeElementAt(0); createNewOnly=true; } } CharClass C=null; int level=-1; String ClassName=""; if(commands.size()>0) { ClassName=(String)commands.elementAt(0); C=CMClass.findCharClass(ClassName); level=CMath.s_int(CMParms.combine(commands,1)); } if((C==null)&&(createNewOnly||(ClassName.toUpperCase().indexOf("ALL")<0))) { mob.tell("Enter 'ALL' for all classes."); try { ClassName=mob.session().prompt("Enter a class name:"); } catch(Exception e){return false;} C=CMClass.findCharClass(ClassName); if((C==null)&&(createNewOnly||(ClassName.toUpperCase().indexOf("ALL")<0))) return false; } if(level<=0) { try { level=CMath.s_int(mob.session().prompt("Enter a level (1-"+CMProps.getIntVar(CMProps.SYSTEMI_LASTPLAYERLEVEL)+"): ")); } catch(Exception e){return false;} if(level<=0) return false; } if(C!=null) mob.session().print("\n\rAverage "+C.name()+"..."); else mob.session().print("\n\rAverage MOB stats, across all classes..."); MOB avgMob=null; if(C!=null) avgMob=AverageClassMOB(mob, level,C, createNewOnly?1:100); else avgMob=AverageAllClassMOB(mob,level, 20, 40); mob.session().println("\n\r"); if(avgMob!=null) { if(createNewOnly) avgMob.bringToLife(mob.location(),true); else { StringBuffer msg=CMLib.commands().getScore(avgMob); if(!mob.isMonster()) mob.session().wraplessPrintln(msg.toString()); avgMob.destroy(); } } return false; } public boolean canBeOrdered(){return true;} public boolean securityCheck(MOB mob){return CMSecurity.isAllowed(mob,mob.location(),"CHARGEN");} }