private static void doAttributes(final Creature cr, final CreatureType ct) {
   int attnum = ct.attnum.aValue();
   final EnumMap<Attribute, Integer> attcap = new EnumMap<Attribute, Integer>(Attribute.class);
   for (final Attribute at : Attribute.values()) {
     if (ct.attributeCap.containsKey(at)) {
       attcap.put(at, ct.attributeCap.get(at).aValue());
     } else {
       attcap.put(at, 10);
     }
   }
   for (final Attribute a : Attribute.values()) {
     attnum -= Math.min(4, cr.skill().getAttribute(a, false));
   }
   while (attnum > 0) {
     Attribute a = i.rng.randFromArray(Attribute.values());
     if (a == WISDOM && cr.alignment() == Alignment.LIBERAL && i.rng.likely(4)) {
       a = HEART;
     }
     if (a == HEART && cr.alignment() == Alignment.CONSERVATIVE && i.rng.likely(4)) {
       a = WISDOM;
     }
     if (cr.skill().getAttribute(a, false) < attcap.get(a)) {
       cr.skill().attribute(a, +1);
       attnum--;
     }
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (i.rng.likely(7)) {
     cr.gender(Gender.FEMALE);
   } else if (i.rng.likely(3)) {
     cr.genderLiberal(Gender.FEMALE);
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (cr.genderLiberal() == Gender.MALE || i.rng.chance(2)) {
     cr.giveArmor("CHEAPSUIT");
   } else {
     cr.giveArmor("CHEAPDRESS");
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (i.issue(Issue.GUNCONTROL).law() == Alignment.ARCHCONSERVATIVE && i.rng.chance(3)) {
     cr.weapon().giveCreatureWeapon("REVOLVER_44:44=4");
   } else if (i.rng.likely(2)) {
     cr.weapon().giveCreatureWeapon("GAVEL");
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   cr.name("Mercenary");
   if (i.issue(Issue.GUNCONTROL).law() == Alignment.ARCHCONSERVATIVE) {
     cr.weapon().giveCreatureWeapon("AUTORIFLE_M16:ASSAULT=7");
   } else {
     cr.weapon().giveCreatureWeapon("SEMIRIFLE_AR15:ASSAULT=7");
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (i.issue(Issue.GUNCONTROL).law() == Alignment.ARCHCONSERVATIVE && i.rng.likely(3)) {
     cr.weapon().giveCreatureWeapon(ct.weapontypes.get(0));
   } else if (i.rng.chance(3)) {
     cr.weapon().giveCreatureWeapon(ct.weapontypes.get(1));
   } else {
     cr.weapon().giveCreatureWeapon(ct.weapontypes.get(2));
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (i.issue(Issue.GUNCONTROL).law() == Alignment.ARCHCONSERVATIVE) {
     cr.weapon().giveCreatureWeapon("SMG_MP5:SMG=4"); // oops, was SGM
   } else if (i.issue(Issue.GUNCONTROL).law() != Alignment.ELITELIBERAL && i.rng.chance(3)) {
     cr.weapon().giveCreatureWeapon("REVOLVER_38:38=4");
   } else {
     cr.weapon().giveCreatureWeapon("NIGHTSTICK");
   }
 }
 /**
  * Suitable job title for this CreatureType. Might be pseudorandom from several, if it's a CCS
  * disguise type.
  *
  * @param c Which creature to give the job title for (random choices are based on their birthday,
  *     so they don't change).
  * @return a suitable job title
  */
 public String jobtitle(final Creature c) {
   if (lcsname.length() != 0 && c.squad() != null) {
     return lcsname;
   }
   if (names.size() == 1) {
     return names.get(0);
   } else if (names.size() == 0) {
     return "Unemployed";
   }
   return names.get(c.birthDay() % names.size());
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (i.issue(Issue.GUNCONTROL).law() == Alignment.ARCHCONSERVATIVE && i.rng.chance(2)
       || i.rng.chance(10)) {
     cr.weapon().giveCreatureWeapon("SHOTGUN_PUMP:BUCKSHOT=4");
   } else if (i.rng.chance(2)) {
     cr.weapon().giveCreatureWeapon("TORCH");
   } else {
     cr.weapon().giveCreatureWeapon("PITCHFORK");
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (i.issue(Issue.GUNCONTROL).law() == Alignment.ARCHCONSERVATIVE && i.rng.chance(3)) {
     cr.weapon().giveCreatureWeapon("SMG_MP5:SMG=4");
   } else if (i.rng.chance(3)) {
     cr.weapon().giveCreatureWeapon("SEMIPISTOL_9MM:9=6");
   } else if (i.rng.chance(2)) {
     cr.weapon().giveCreatureWeapon("SHOTGUN_PUMP:BUCKSHOT=4");
   } else {
     cr.weapon().giveCreatureWeapon("NIGHTSTICK");
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (i.issue(Issue.GUNCONTROL).law() == Alignment.CONSERVATIVE && i.rng.chance(30)) {
     cr.weapon().giveCreatureWeapon("REVOLVER_38:38=4");
   } else if (i.issue(Issue.GUNCONTROL).law() == Alignment.ARCHCONSERVATIVE) {
     if (i.rng.chance(10)) {
       cr.weapon().giveCreatureWeapon("SEMIPISTOL_9MM:9=4");
     } else if (i.rng.chance(9)) {
       cr.weapon().giveCreatureWeapon("SEMIPISTOL_45:45=4");
     }
   }
 }
 /**
  * Whether we are disguised as a particular creature...
  *
  * @param cr a creature to test (in the case of multiple matches, their birthday is used to
  *     determine which one they're disguised as).
  * @return A CreatureType, or null.
  */
 static CreatureType inCharacter(final Creature cr) {
   final List<CreatureType> valid = new ArrayList<CreatureType>();
   for (final CreatureType c : Game.type.creature.values()) {
     if (!c.hasUniform()) {
       continue;
     }
     if (c.uniform != null && c.uniform.inCharacter(cr)) {
       valid.add(c);
     }
   }
   if (valid.size() == 0) {
     return cr.type();
   }
   return valid.get(cr.birthDay() % valid.size());
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (i.mode() == GameMode.SITE && i.site.current().highSecurity() != 0) {
     cr.name("Enforcer");
     cr.skill().setSkill(CLUB, i.rng.nextInt(3) + 3);
   }
   cr.weapon()
       .giveCreatureWeapon(
           ct.weapontypes.get(i.issue(Issue.GUNCONTROL).law().trueOrdinal() + 2));
   if (i.site.type().disguisesite()) {
     cr.alignment(Alignment.CONSERVATIVE);
     cr.infiltration(i.rng.nextInt(40));
   } else {
     cr.alignment(Alignment.MODERATE);
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (i.rng.chance(20)
       || i.issue(Issue.GUNCONTROL).law() == Alignment.ARCHCONSERVATIVE && i.rng.chance(5)) {
     cr.weapon().giveCreatureWeapon("AUTORIFLE_AK47:ASSAULT=3");
   } else if (i.rng.chance(16)
       || i.issue(Issue.GUNCONTROL).law() == Alignment.ARCHCONSERVATIVE && i.rng.chance(5)) {
     cr.weapon().giveCreatureWeapon("SMG_MP5:SMG=4");
   } else if (i.rng.chance(15)) {
     cr.weapon().giveCreatureWeapon("SEMIPISTOL_45:45=4");
   } else if (i.rng.chance(10)) {
     cr.weapon().giveCreatureWeapon("SHOTGUN_PUMP:BUCKSHOT=4");
   } else if (i.rng.chance(4)) {
     cr.weapon().giveCreatureWeapon("SEMIPISTOL_9MM:9=4");
   } else if (i.rng.chance(2)) {
     cr.weapon().giveCreatureWeapon("REVOLVER_38:38=4");
   } else {
     cr.weapon().giveCreatureWeapon("KNIFE");
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   final int level = i.rng.nextInt(5) + i.endgameState.ordinal();
   cr.weapon().giveCreatureWeapon(ct.weapontypes.get(level));
   cr.giveArmor(ct.armorTypes.get(level));
 }
 /**
  * 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
 void apply(final Creature cr, final CreatureType ct) {
   if (i.site.alarm()) {
     cr.giveArmor("BUNKERGEAR");
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   cr.properName(new CreatureName(Gender.WHITEMALEPATRIARCH, Animal.HUMAN));
   cr.name("CEO " + cr.properName());
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (i.rng.chance(10)) {
     // Thief
     cr.skill().setSkill(SECURITY, i.rng.nextInt(5) + 3);
     cr.skill().setSkill(DISGUISE, i.rng.nextInt(5) + 3);
     cr.skill().setSkill(STEALTH, i.rng.nextInt(5) + 3);
     // cr.set_skill(THEFT,i.rng.getInt(5)+3);
     cr.type(CreatureType.valueOf("THIEF"));
     cr.age(Age.MATURE.age());
   } else {
     switch (i.rng.nextInt(5)) {
       default:
         // Gang member
         cr.skill().setSkill(PISTOL, i.rng.nextInt(2) + 1);
         cr.skill().setSkill(SHOTGUN, i.rng.nextInt(2) + 1);
         cr.skill().setSkill(RIFLE, i.rng.nextInt(2) + 1);
         cr.type(CreatureType.valueOf("GANGMEMBER"));
         cr.age(Age.YOUNGADULT.age());
         break;
       case 1:
         // Prostitute
         cr.skill().setSkill(PERSUASION, i.rng.nextInt(4) + 2);
         cr.skill().setSkill(SEDUCTION, i.rng.nextInt(4) + 2);
         cr.type(CreatureType.valueOf("PROSTITUTE"));
         cr.age(Age.YOUNGADULT.age());
         break;
       case 2:
         // Crack head
         cr.skill().setSkill(Skill.SHOOTINGUP, 10);
         cr.type(CreatureType.valueOf("CRACKHEAD"));
         cr.age(Age.YOUNGADULT.age());
         break;
       case 3:
         // Teenager
         cr.age(Age.TEENAGER.age());
         cr.type(CreatureType.valueOf("TEENAGER"));
         break;
       case 4:
         // HS Dropout
         cr.age(Age.TEENAGER.age());
         cr.type(CreatureType.valueOf("HSDROPOUT"));
         break;
     }
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   cr.alignment(i.rng.choice(Alignment.MODERATE, Alignment.LIBERAL));
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   cr.gender(ct.gender);
 }
 private static void doRandomSkills(final Creature cr) {
   int randomskills = i.rng.nextInt(4) + 4;
   if (cr.age() > 20) {
     randomskills += randomskills * (cr.age() - 20.0) / 20.0;
   } else {
     randomskills -= (20 - cr.age()) / 2;
   }
   // RANDOM STARTING SKILLS
   while (randomskills > 0) {
     final Skill randomskill = i.rng.randFromArray(Skill.values());
     // 95% chance of not allowing some skills for anybody...
     if (randomskill == Skill.SHOOTINGUP) {
       continue; // don't automatically give skill in this, it's not useful
     }
     if (i.rng.likely(20)
         && (randomskill == HEAVYWEAPONS
             || randomskill == SMG
             || randomskill == SWORD
             || randomskill == RIFLE
             || randomskill == AXE
             || randomskill == CLUB
             || randomskill == PSYCHOLOGY)) {
       continue;
     }
     // 90% chance of not allowing some skills, other than
     // for conservatives
     if (i.rng.likely(10) && cr.alignment() != Alignment.CONSERVATIVE) {
       if (randomskill == SHOTGUN) {
         continue;
       }
       if (randomskill == PISTOL) {
         continue;
       }
     }
     if (cr.skill().skillCap(randomskill, true) > cr.skill().skill(randomskill)) {
       cr.skill().setSkill(randomskill, cr.skill().skill(randomskill) + 1);
       randomskills--;
     }
     while (true) {
       if (randomskills != 0
           && i.rng.likely(2)
           && cr.skill().skillCap(randomskill, true) > cr.skill().skill(randomskill)
           && cr.skill().skill(randomskill) < 4) {
         cr.skill().setSkill(randomskill, cr.skill().skill(randomskill) + 1);
         randomskills--;
       } else {
         break;
       }
     }
   }
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   cr.addFlag(CreatureFlag.ILLEGAL_ALIEN);
 }
 @Override
 void apply(final Creature cr, final CreatureType ct) {
   if (i.site.current().type().isType("CORPORATE_HOUSE")) {
     cr.name("Pet ");
   } else {
     cr.name("");
   }
   switch (i.rng.nextInt(11)) {
     default:
       cr.name(cr.toString() + "Genetic Monster");
       break;
     case 1:
       {
         cr.name(cr.toString() + "Flaming Rabbit");
         cr.specialAttack(SpecialAttacks.FLAME);
         break;
       }
     case 2:
       cr.name(cr.toString() + "Genetic Nightmare");
       break;
     case 3:
       cr.name(cr.toString() + "Mad Cow");
       break;
     case 4:
       {
         cr.name(cr.toString() + "Giant Mosquito");
         cr.specialAttack(SpecialAttacks.SUCK);
         break;
       }
     case 5:
       cr.name(cr.toString() + "Six-legged Pig");
       break;
     case 6:
       cr.name(cr.toString() + "Purple Gorilla");
       break;
     case 7:
       cr.name(cr.toString() + "Warped Bear");
       break;
     case 8:
       cr.name(cr.toString() + "Writhing Mass");
       break;
     case 9:
       cr.name(cr.toString() + "Something Bad");
       break;
     case 10:
       cr.name(cr.toString() + "Pink Elephant");
       break;
   }
 }
 private static void doInfiltration(final Creature cr, final CreatureType ct) {
   if (ct.infiltration.base != 0 && ct.infiltration.range != 0) {
     cr.infiltration(ct.infiltration.aValue());
   } else if (cr.alignment() == Alignment.LIBERAL) {
     cr.infiltration(15 + i.rng.nextInt(10) - 5);
   } else if (cr.alignment() == Alignment.MODERATE) {
     cr.infiltration(25 + i.rng.nextInt(10) - 5);
   } else {
     cr.infiltration(cr.infiltration() + 35 * (1 - cr.infiltration()) + i.rng.nextInt(10) - 5);
   }
   if (cr.infiltration() < 0) {
     cr.infiltration(0);
   }
   if (cr.infiltration() > 100) {
     cr.infiltration(100);
   }
 }