/**
  * Create a Creature with a given type.
  *
  * @param template the CreatureType to create.
  * @return a Creature.
  */
 public static Creature withType(final CreatureType template) {
   CreatureType modifiedTemplate = template;
   if (modifiedTemplate == CreatureType.valueOf("COP")
       && i.issue(Issue.POLICEBEHAVIOR).law() == Alignment.ELITELIBERAL
       && template.alignment == Alignment.LIBERAL
       && i.rng.likely(3)) {
     modifiedTemplate = CreatureType.valueOf("POLICE_NEGOTIATOR");
   }
   if (modifiedTemplate == CreatureType.valueOf("DEATHSQUAD")
       && i.issue(Issue.DEATHPENALTY).law() != Alignment.ARCHCONSERVATIVE
       && i.issue(Issue.POLICEBEHAVIOR).law() != Alignment.ARCHCONSERVATIVE) {
     if (i.issue(Issue.POLICEBEHAVIOR).lawLT(Alignment.CONSERVATIVE) && i.rng.chance(2)) {
       modifiedTemplate = CreatureType.valueOf("GANGUNIT");
     } else {
       modifiedTemplate = CreatureType.valueOf("SWAT");
     }
   }
   if (modifiedTemplate == CreatureType.valueOf("FIREFIGHTER") && !i.freeSpeech()) {
     modifiedTemplate = CreatureType.valueOf("FIREMAN");
   }
   final Creature cr = new Creature(modifiedTemplate.animalGloss, modifiedTemplate);
   cr.squad(null);
   cr.type(modifiedTemplate);
   if (modifiedTemplate.names.size() > 0) {
     cr.name(i.rng.randFromList(modifiedTemplate.names));
   } else if (modifiedTemplate.ccs && i.mode() == GameMode.SITE) {
     cr.nameCCSMember();
   } else {
     cr.name(modifiedTemplate.toString());
   }
   if (modifiedTemplate.armorTypes.size() > 0) {
     cr.giveArmor(i.rng.randFromList(modifiedTemplate.armorTypes));
   } else {
     cr.giveArmor("CLOTHES");
   }
   if (modifiedTemplate.weapontypes.size() > 0) {
     cr.weapon().giveCreatureWeapon(i.rng.randFromList(modifiedTemplate.weapontypes));
   }
   cr.juice(modifiedTemplate.juice.aValue());
   cr.money(modifiedTemplate.money.aValue());
   final int mood = Politics.publicmood();
   cr.conservatise();
   if (i.rng.nextInt(100) < mood) {
     cr.alignment(cr.alignment().next());
   }
   if (i.rng.nextInt(100) < mood) {
     cr.alignment(cr.alignment().next());
   }
   if (modifiedTemplate.animalGloss == Animal.TANK) {
     cr.specialAttack(SpecialAttacks.CANNON);
   }
   if (modifiedTemplate.verifyworklocation(i.site.current())) {
     cr.workLocation(i.site.current());
   } else {
     cr.workLocation(modifiedTemplate.workLocation());
   }
   cr.age(modifiedTemplate.age.age());
   final boolean traditionalgenderroles =
       i.issue(Issue.WOMEN).law() == Alignment.ARCHCONSERVATIVE
           || i.issue(Issue.WOMEN).law() == Alignment.CONSERVATIVE && i.rng.likely(25)
           || i.issue(Issue.WOMEN).law() == Alignment.MODERATE && i.rng.likely(10)
           || i.issue(Issue.WOMEN).law() == Alignment.LIBERAL && i.rng.likely(4);
   if (traditionalgenderroles) {
     if (modifiedTemplate.gender == Gender.MALE) {
       cr.gender(Gender.MALE);
     } else if (modifiedTemplate.gender == Gender.FEMALE) {
       cr.gender(Gender.FEMALE);
     }
   }
   cr.alignment(modifiedTemplate.alignment);
   for (final Entry<Skill, Range> e : modifiedTemplate.skills.entrySet()) {
     cr.skill().setSkill(e.getKey(), e.getValue().aValue());
   }
   for (final Entry<Attribute, Range> e : modifiedTemplate.attribute.entrySet()) {
     cr.skill().attribute(e.getKey(), e.getValue().aValue());
   }
   if (modifiedTemplate.offences.size() > 0) {
     final Crime lf = i.rng.randFromList(modifiedTemplate.offences);
     cr.crime().criminalize(lf);
   }
   for (final Specials s : modifiedTemplate.specials) {
     s.apply(cr, modifiedTemplate);
   }
   doAttributes(cr, modifiedTemplate);
   if (modifiedTemplate.stub) {
     return cr;
   }
   doInfiltration(cr, modifiedTemplate);
   doRandomSkills(cr);
   // ALIENATION
   if (i.site.alienate() != Alienation.NONE && cr.alignment() == Alignment.MODERATE) {
     cr.conservatise();
   }
   if (i.site.alienate() == Alienation.ALL && cr.alignment() == Alignment.LIBERAL) {
     cr.conservatise();
   }
   return cr;
 }
 @Override
 public void xmlSet(final String key, final String value) {
   switch (mode) {
     case DEFAULT:
       if ("age".equals(key)) {
         age = Age.valueOf(Xml.getText(value));
       } else if ("gender".equals(key)) {
         gender = Gender.valueOf(Xml.getText(value));
       } else if ("alignment".equals(key)) {
         alignment = Enum.valueOf(Alignment.class, Xml.getText(value));
       } else if ("money".equals(key)) {
         money = new Range(Xml.getText(value));
       } else if ("juice".equals(key)) {
         juice = new Range(Xml.getText(value));
       } else if ("infiltration".equals(key)) {
         infiltration = new Range(Xml.getText(value));
       } else if ("ccs".equals(key)) {
         ccs = Xml.getBoolean(value);
       } else if ("animalgloss".equals(key)) {
         animalGloss = Animal.valueOf(value);
       } else if ("lcsname".equals(key)) {
         lcsname = Xml.getText(value);
       } else if ("attnum".equals(key)) {
         attnum = new Range(Xml.getText(value));
       } else if ("teaches".equals(key)) {
         teaches = Activity.valueOf(value);
       } else if ("police".equals(key)) {
         police = Xml.getBoolean(value);
       } else if ("observationskill".equals(key)) {
         observationSkill = CheckDifficulty.valueOf(value);
       } else if ("receptive".equals(key)) {
         receptive = Xml.getBoolean(value);
       } else if ("coreskill".equals(key)) {
         coreSkill = Skill.valueOf(value);
       } else if ("influence".equals(key)) {
         influence = Xml.getInt(value);
       } else if ("seduce".equals(key)) {
         seduce = CheckDifficulty.valueOf(value);
       } else if ("stub".equals(key)) {
         stub = Xml.getBoolean(value);
       } else {
         Log.w(Game.LCS, "Oops: " + key + "=" + value);
       }
       break;
     case ARMOR:
       if ("item".equals(key)) {
         final ArmorType at = Game.type.armor.get("ARMOR_" + Xml.getText(value));
         if (at == null) {
           Log.e(Game.LCS, "No such armortype:" + Xml.getText(value));
         } else {
           armorTypes.add(at);
         }
       } else {
         Log.w(Game.LCS, "Bad key:" + key + "=" + value);
       }
       break;
     case WEAPON:
       if ("item".equals(key)) {
         weapontypes.add(new WeaponAssigner(Xml.getText(value)));
       } else {
         Log.w(Game.LCS, "Bad key:" + key + "=" + value);
       }
       break;
     case NAMES:
       if ("item".equals(key)) {
         names.add(Xml.getText(value));
       } else {
         Log.w(Game.LCS, "Bad key:" + key + "=" + value);
       }
       break;
     case SPECIALS:
       if ("item".equals(key)) {
         specials.add(Specials.valueOf(Xml.getText(value)));
       } else {
         Log.w(Game.LCS, "Bad key:" + key + "=" + value);
       }
       break;
     case WORKLOCATION:
       if ("item".equals(key)) {
         workLocation.add(AbstractSiteType.type(value));
       } else {
         Log.w(Game.LCS, "Bad key:" + key + "=" + value);
       }
       break;
     case SKILL:
       skills.put(Skill.valueOf(key), new Range(value));
       break;
     case ATTCAP:
       attributeCap.put(Attribute.valueOf(key), new Range(value));
       break;
     case ATTRIBUTE:
       attribute.put(Attribute.valueOf(key), new Range(value));
       break;
     case CRIMES:
       if (value.length() != 0) {
         offences.add(Crime.valueOf(value));
       } else {
         offences.add(null);
       }
       break;
     default:
       Log.e("LCS", "CreatureType xmlSet default:" + mode);
   }
 }