/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package asis;
import asis.ini.INI;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import skyproc.*;
import skyproc.gui.SPProgressBarPlug;
/**
*
* @author pc tech
*/
public class AutomaticPerks {
public void addPerks() {
internalAddPerks();
}
public void addPerks(ASIS a) {
if (a.getModExclusions() != null) {
NPCModExclusions.addAll(a.getModExclusions());
perkModExclusions.addAll(a.getModExclusions());
}
internalAddPerks();
}
private void internalAddPerks() {
SPProgressBarPlug.setStatus("Automatic Perks: Starting Patch");
SPProgressBarPlug.incrementBar();
Mod merger = new Mod("TmpMerger", false);
merger.addAsOverrides(SPGlobal.getDB());
processINI();
getSkillIndices();
getPerkLists(merger);
addPerksToNPCs(merger);
addPerksToFollowers(merger);
}
private void addPerksToNPCs(Mod merger) {
SPProgressBarPlug.setStatus("Automatic Perks: Adding Perks to NPCs");
SPProgressBarPlug.incrementBar();
int conditionsMet;
int temp;
int perkNum;
Skill tempSkill;
boolean npcInclude;
boolean perkInclude;
ArrayList<Perk> tempToRemove = new ArrayList<>();
for (Perk p : perks) {
perkInclude = getValidPerk(p);
if (!perkInclude) {
tempToRemove.add(p);
}
}
perks.removeAll(tempToRemove);
for (NPC_ n : merger.getNPCs()) {
npcInclude = getValidNPC(n);
if (npcInclude) {
if (!n.getPerks().isEmpty()) {
perkNum = n.getPerks().get(0).getNum();
} else {
perkNum = 0;
}
for (Perk p : perks) {
conditionsMet = 0;
for (int i = 0; i < p.getNumConditionals(); i++) {
temp = p.getPerkType(i);
if (temp != -1) {
tempSkill = perkSettingsMap.get(temp);
if (n.get(tempSkill) > p.getPerkLevel(i)) {
conditionsMet++;
}
}
if (conditionsMet >= p.getNumConditionals()) {
n.addPerk(p.getPerkForm(), perkNum);
if (nextPerksMap.containsKey(p.getPerkForm())) {
n.removePerk(nextPerksMap.get(p.getPerkForm()));
}
SPGlobal.getGlobalPatch().addRecord(n);
}
}
}
}
}
//Clean-up NPC's from excluded mods. This is done as blocking the import
// could cause previous NPC's to override an excluded mods NPC's.
String list;
Mod tempMod;
GRUP patchGRUP = SPGlobal.getGlobalPatch().getNPCs();
for (int i = 0; i < NPCModExclusions.size(); i++) {
list = (String) NPCModExclusions.get(i);
try {
tempMod = SPGlobal.getDB().getMod(new ModListing(list));
for (NPC_ n : tempMod.getNPCs()) {
patchGRUP.removeRecord(n.getForm());
}
} catch (Exception e) {
//Do nothing, probably doesn't have the mod in the exclusions.
}
}
}
private void addPerksToFollowers(Mod merger) {
SPProgressBarPlug.setStatus("Automatic Perks: Adding Perks to Followers");
SPProgressBarPlug.incrementBar();
int conditionsMet;
int temp;
int perkNum;
Skill tempSkill;
boolean npcInclude;
boolean perkInclude;
FormID hirelingFaction = new FormID("0BCC9A", SPGlobal.getDB().getMod(new ModListing("Skyrim", true)).getInfo());
FormID followerFaction = new FormID("05C84D", SPGlobal.getDB().getMod(new ModListing("Skyrim", true)).getInfo());
for (NPC_ n : merger.getNPCs()) {
npcInclude = getValidFollower(n, followerFaction, hirelingFaction);
if (npcInclude) {
if (!n.getPerks().isEmpty()) {
perkNum = n.getPerks().get(0).getNum();
} else {
perkNum = 0;
}
for (Perk p : perks) {
/*
* if (n.getEDID().contains("EncDremoraWarlock06") &&
* p.getEDID().contains("AugmentedShock60")) { int abc = 0;
* }
*/
conditionsMet = 0;
perkInclude = getValidPerk(p);
if (perkInclude) {
for (int i = 0; i < p.getNumConditionals(); i++) {
temp = p.getPerkType(i);
if (temp != -1) {
tempSkill = perkSettingsMap.get(temp);
if (n.get(tempSkill) > p.getPerkLevel(i)) {
conditionsMet++;
}
}
}
if (conditionsMet >= p.getNumConditionals()) {
n.addPerk(p.getPerkForm(), perkNum);
if (nextPerksMap.containsKey(p.getPerkForm())) {
n.removePerk(nextPerksMap.get(p.getPerkForm()));
}
SPGlobal.getGlobalPatch().addRecord(n);
}
}
}
}
}
}
private void getPerkLists(Mod merger) {
SPProgressBarPlug.setStatus("Automatic Perks: Mapping Perks");
SPProgressBarPlug.incrementBar();
Perk tempPerk = null;
FormID nextPerkForm;
int numConditions;
boolean perkUsed;
for (PERK p : merger.getPerks()) {
perkUsed = false;
numConditions = 0;
for (int i = 0; i < p.getSizeOfCTDAs(); i++) {
if (p.getComparison(i) == 96 && p.getComparisonFunction(i) == 277 && !perkUsed) {
if (p.getNextPerkForm() != null) {
nextPerkForm = p.getNextPerkForm();
nextPerksMap.put(nextPerkForm, p.getForm());
} else {
nextPerkForm = p.getForm();
}
tempPerk = new Perk(p, p.getActorValue(i), p.getComparisonValue(i), nextPerkForm);
perks.add(tempPerk);
numConditions++;
} else if (p.getComparison(i) == 96 && p.getComparisonFunction(i) == 277 && perkUsed) {
tempPerk.addConditional(p.getActorValue(i), p.getComparisonValue(i));
}
}
}
}
private boolean getValidFollower(NPC_ n, FormID followerFaction, FormID hirelingFaction) {
boolean npcExclude = false;
boolean npcInclude = false;
for (int i = 0; i < n.getFactions().size(); i++) {
if (n.getFactions().get(i).getForm().get() == followerFaction.get()
|| n.getFactions().get(i).getForm().get() == hirelingFaction.get()) {
npcInclude = true;
}
}
String list;
for (int i = 0; i < NPCModExclusions.size(); i++) {
list = (String) NPCModExclusions.get(i);
if (n.getFormMaster().equals(new ModListing(list))) {
npcExclude = true;
break;
}
}
if (npcInclude && !npcExclude) {
return true;
} else {
return false;
}
}
private boolean getValidNPC(NPC_ n) {
boolean npcExclude = false;
boolean npcInclude = false;
String list;
String edid = n.getEDID().toUpperCase();
if (npcInclusions.isEmpty()) {
npcInclude = true;
}
if (!npcInclude) {
for (int i = 0; i < npcInclusions.size(); i++) {
list = ((String) npcInclusions.get(i));
if (edid.contains(list)) {
npcInclude = true;
break;
}
}
}
if (npcExclusions.isEmpty() && NPCModExclusions.isEmpty()) {
npcExclude = false;
}
if (npcInclude && !npcExclude) {
for (int i = 0; i < npcExclusions.size(); i++) {
list = ((String) npcExclusions.get(i));
if (edid.contains(list)) {
npcExclude = true;
break;
}
}
for (int i = 0; i < NPCModExclusions.size(); i++) {
list = (String) NPCModExclusions.get(i);
if (n.getFormMaster().equals(new ModListing(list))) {
npcExclude = true;
break;
}
}
}
if (npcInclude && !npcExclude) {
return true;
} else {
return false;
}
}
private boolean getValidPerk(Perk p) {
boolean perkExclude = false;
boolean perkInclude = false;
String list;
String edid = p.getEDID().toUpperCase();
if (perkInclusions.isEmpty()) {
perkInclude = true;
}
if (!perkInclude) {
for (int i = 0; i < perkInclusions.size(); i++) {
list = ((String) perkInclusions.get(i));
if (edid.contains(list)) {
perkInclude = true;
break;
}
}
}
if (perkExclusions.isEmpty() && perkExclusionsStartsWith.isEmpty() && perkModExclusions.isEmpty()) {
perkExclude = false;
} else if (perkInclude) {
for (int i = 0; i < perkExclusionsStartsWith.size(); i++) {
list = ((String) perkExclusionsStartsWith.get(i));
if (edid.startsWith(list)) {
perkExclude = true;
break;
}
}
if (!perkExclude) {
for (int i = 0; i < perkExclusions.size(); i++) {
list = ((String) perkExclusions.get(i));
if (edid.contains(list)) {
perkExclude = true;
break;
}
}
}
if (!perkExclude) {
for (int i = 0; i < perkModExclusions.size(); i++) {
list = (String) perkModExclusions.get(i);
if (p.getModMaster().equals(new ModListing(list))) {
perkExclude = true;
break;
}
}
}
}
if (perkInclude && !perkExclude) {
return true;
} else {
return false;
}
}
private void getSkillIndices() {
int i = 6;
for (Skill s : Skill.values()) {
perkSettingsMap.put(i, s);
i++;
}
}
private void processINI() {
SPProgressBarPlug.setStatus("Automatic Perks: Processing INI");
SPProgressBarPlug.incrementBar();
//Sets up the file reader for the ini file.
INI ini = null;
//Sets up the file reader for the ini file.
try {
ini = new INI("AutomaticPerks.ini");
} catch (IOException ex) {
Logger.getLogger(NPCPotions.class.getName()).log(Level.SEVERE, null, ex);
}
Collection<INI.IniSectionHead> sections = getSectionList();
ini.addSection(sections);
try {
ini.readData();
} catch (IOException ex) {
Logger.getLogger(NPCPotions.class.getName()).log(Level.SEVERE, null, ex);
}
initializeLists(ini);
}
private Collection<INI.IniSectionHead> getSectionList() {
Collection<INI.IniSectionHead> sectionList = new ArrayList<>();
for (IniSection currentSection : IniSection.values()) {
sectionList.add(new INI.IniSectionHead(currentSection.getName(), currentSection.getFormat()));
}
return sectionList;
}
private void initializeLists(INI ini) {
npcInclusions = (ArrayList) ini.getCollection(new INI.IniSectionHead(IniSection.NPCINCLUSIONS.getName(),
IniSection.NPCINCLUSIONS.getFormat()));
for (int i = 0; i < npcInclusions.size(); i++) {
npcInclusions.set(i, ((String) npcInclusions.get(i)).toUpperCase());
}
npcExclusions = (ArrayList) ini.getCollection(new INI.IniSectionHead(IniSection.NPCEXCLUSIONS.getName(),
IniSection.NPCEXCLUSIONS.getFormat()));
for (int i = 0; i < npcExclusions.size(); i++) {
npcExclusions.set(i, ((String) npcExclusions.get(i)).toUpperCase());
}
NPCModExclusions.addAll((ArrayList) ini.getCollection(new INI.IniSectionHead(IniSection.NPCMODEXCLUSIONS.getName(),
IniSection.NPCMODEXCLUSIONS.getFormat())));
perkExclusions = (ArrayList) ini.getCollection(new INI.IniSectionHead(IniSection.PERKEXCLUSIONSCONTAINS.getName(),
IniSection.PERKEXCLUSIONSCONTAINS.getFormat()));
for (int i = 0; i < perkExclusions.size(); i++) {
perkExclusions.set(i, ((String) perkExclusions.get(i)).toUpperCase());
}
perkExclusionsStartsWith = (ArrayList) ini.getCollection(new INI.IniSectionHead(IniSection.PERKEXCLUSIONSSTARTSWITH.getName(),
IniSection.PERKEXCLUSIONSSTARTSWITH.getFormat()));
for (int i = 0; i < perkExclusionsStartsWith.size(); i++) {
perkExclusionsStartsWith.set(i, ((String) perkExclusionsStartsWith.get(i)).toUpperCase());
}
perkModExclusions.addAll((ArrayList) ini.getCollection(new INI.IniSectionHead(IniSection.PERKMODEXCLUSIONS.getName(),
IniSection.PERKMODEXCLUSIONS.getFormat())));
perkInclusions = (ArrayList) ini.getCollection(new INI.IniSectionHead(IniSection.PERKINCLUSIONS.getName(),
IniSection.PERKINCLUSIONS.getFormat()));
for (int i = 0; i < perkInclusions.size(); i++) {
perkInclusions.set(i, ((String) perkInclusions.get(i)).toUpperCase());
}
}
private enum IniSection {
PERKSETTINGS(INI.IniDataFormat.KEY_VALUE, "PERKSETTINGS"),
NPCINCLUSIONS(INI.IniDataFormat.VALUE, "NPCINCLUSIONS"),
NPCEXCLUSIONS(INI.IniDataFormat.VALUE, "NPCEXCLUSIONS"),
NPCMODEXCLUSIONS(INI.IniDataFormat.VALUE, "NPCMODEXCLUSIONS"),
PERKEXCLUSIONSCONTAINS(INI.IniDataFormat.VALUE, "PERKEXCLUSIONSCONTAINS"),
PERKEXCLUSIONSSTARTSWITH(INI.IniDataFormat.VALUE, "PERKEXCLUSIONSSTARTSWITH"),
PERKMODEXCLUSIONS(INI.IniDataFormat.VALUE, "PERKMODEXCLUSIONS"),
PERKINCLUSIONS(INI.IniDataFormat.VALUE, "PERKINCLUSIONS");
private INI.IniDataFormat format;
private String name;
IniSection(INI.IniDataFormat format, String name) {
this.format = format;
this.name = name;
}
String getName() {
return name;
}
INI.IniDataFormat getFormat() {
return format;
}
}
static String settingType = null;
static String settingValue = null;
static int perkLevel;
static Skill spellType;
static int[] skillLevels = {0, 0, 0, 0, 0};
static ArrayList npcInclusions = new ArrayList<>(0);
static ArrayList npcExclusions = new ArrayList<>(0);
static ArrayList NPCModExclusions = new ArrayList<>(0);
static ArrayList perkInclusions = new ArrayList<>(0);
static ArrayList perkExclusions = new ArrayList<>(0);
static ArrayList perkExclusionsStartsWith = new ArrayList<>(0);
static ArrayList perkModExclusions = new ArrayList<>(0);
static ArrayList perkSettings = new ArrayList<>(0);
ArrayList<FormID> npcBlockList = new ArrayList<>();
ArrayList<FormID> spellBlockList = new ArrayList<>();
static ArrayList<Perk> perks = new ArrayList<>();
static Map<Integer, Skill> perkSettingsMap = new LinkedHashMap<>();
static Map<FormID, FormID> nextPerksMap = new HashMap<>();
public static int numProgressSections = 5;
}