--- Adds extra traits for the players to choose from
-- @author QueuedResonance 2022, SolarEdge 2024

require('NPCs/MainCreationMethods')

local TraitFactory = TraitFactory
local Perks = Perks

local getText = getText
local string = string

------------------------------------------------------------ Traits ------------------------------------------------------------

--- Table of all the traits relevant to ZomboLewd
local TRAITS_LIST = {
	{
		IdentifierType = "Sexaddict",
		Cost = -4,
		Profession = false,
		MutualExclusives = {},
	},
	{
		--Will return in future update.
		IdentifierType = "Masochist",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
		Callback = function(trait)
			trait:addXPBoost(Perks.Lightfoot, 1)
		end
	},
	{
		IdentifierType = "Rapist",
		Cost = 4,
		Profession = false,
		MutualExclusives = {},
		Callback = function(trait)
			trait:addXPBoost(Perks.Sneak, 1)
		end
	},
	{
		IdentifierType = "Wimp", --- Fear of rape
		Cost = -4,
		Profession = false,
		MutualExclusives = {},
		-- Trait implemented
	},
	{
		IdentifierType = "Necrophiliac",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		--Will return in future update.
		IdentifierType = "Misogynist",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		--Will return in future update.
		IdentifierType = "Misandrist",
		Cost = 0,
		Profession = false,
		MutualExclusives = {"Misogynist"},
	},
	{
		IdentifierType = "Everydrop",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Virgin",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Inexperienced",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Experienced",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Nymphomaniac",
		Cost = 6,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Innocent",
		Cost = -3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Lewd",
		Cost = 4,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Traumatized",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "drinkerNoob",
		Cost = 1,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "drinkerLight",
		Cost = 1,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "drinkerHeavy",
		Cost = 1,
		Profession = false,
		MutualExclusives = {},
	},
		{
		IdentifierType = "pacify",
		Cost = 2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "succubus",
		Cost = 2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		--Implemented but unused, joke trait.
		IdentifierType = "gonorrhea",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		--Future update
		IdentifierType = "AIDS",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Fugly",
		Cost = -3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "submissive",
		Cost = -6,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "dominate",
		Cost = 5,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "youngBuck",
		Cost = 4,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "AARP",
		Cost = -4,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "inPrime",
		Cost = 2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "spunkDefault",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "lowEffort",
		Cost = 6,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "smokesAfter",
		Cost = -2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "betterAlive",
		Cost = -6,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "buttonedUp",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "baggyStyle",
		Cost = -3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "itFollows",
		Cost = -8,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "promiscuous",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "swinger",
		Cost = 2,
		Profession = false,
		MutualExclusives = {},
	},
	-- Showering conditions have not yet been established: originally 'Cost = -6' --
	{
		IdentifierType = "noColdShowers",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "unkempt",
		Cost = -5,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "dislikesShowers",
		Cost = -2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "neatTidy",
		Cost = 2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "lovesClean",
		Cost = 5,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "viciousZombies",
		Cost = -5,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "dpress",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "cute",
		Cost = 6,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "unblessing",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "bisex",
		Cost = -2,
		Profession = false,
		MutualExclusives = {},
	},
}

--- Load ZomboLewd specific traits
local function _initTraits()
	for i = 1, #TRAITS_LIST do
		local data = TRAITS_LIST[i]

		local name = getText(string.format("UI_ZL_Trait_%s", data.IdentifierType))
		local desc = getText(string.format("UI_ZL_Trait_%s_Description", data.IdentifierType))
		local newTrait = TraitFactory.addTrait(data.IdentifierType, name, data.Cost, desc, data.Profession)

		--- Activate optional callbacks
		if data.Callback then
			data.Callback(newTrait)
		end

		--- Make it so traits with mutual exclusivity can't select each other
		for v = 1, #data.MutualExclusives do
			TraitFactory.setMutualExclusive(data.IdentifierType, data.MutualExclusives[v])
		end
	end
	--- Manual trait exclusives
	TraitFactory.setMutualExclusive("Virgin", "Inexperienced");
	TraitFactory.setMutualExclusive("Virgin", "Experienced");
	TraitFactory.setMutualExclusive("Virgin", "Nymphomaniac");
	--TraitFactory.setMutualExclusive("Virgin", "Lewd"); Deleted because people can be virgins and lewd.
	TraitFactory.setMutualExclusive("Virgin", "Everydrop"); --I'm aware, yes, but no.
	TraitFactory.setMutualExclusive("Inexperienced", "Experienced");
	TraitFactory.setMutualExclusive("Inexperienced", "Nymphomaniac");
	TraitFactory.setMutualExclusive("Experienced", "Nymphomaniac");
	TraitFactory.setMutualExclusive("Innocent", "Everydrop");
	TraitFactory.setMutualExclusive("Innocent", "Lewd");
	TraitFactory.setMutualExclusive("Innocent", "Nymphomaniac");
	TraitFactory.setMutualExclusive("Innocent", "Sexaddict");
	TraitFactory.setMutualExclusive("Innocent", "succubus");
	TraitFactory.setMutualExclusive("Innocent", "Rapist");
	TraitFactory.setMutualExclusive("Wimp", "Rapist");
	TraitFactory.setMutualExclusive("Wimp", "Masochist");
	TraitFactory.setMutualExclusive("Wimp", "Nymphomaniac");
	TraitFactory.setMutualExclusive("Wimp", "Lewd");
	TraitFactory.setMutualExclusive("drinkerNoob", "drinkerLight");
	TraitFactory.setMutualExclusive("drinkerNoob", "drinkerHeavy");
	TraitFactory.setMutualExclusive("drinkerLight", "drinkerHeavy");
	TraitFactory.setMutualExclusive("pacify", "succubus");
	TraitFactory.setMutualExclusive("succubus", "Everydrop");
	TraitFactory.setMutualExclusive("dominate", "submissive");
	TraitFactory.setMutualExclusive("dominate", "Wimp");
	TraitFactory.setMutualExclusive("youngBuck", "AARP");
	TraitFactory.setMutualExclusive("youngBuck", "inPrime");
	TraitFactory.setMutualExclusive("AARP", "inPrime");
	TraitFactory.setMutualExclusive("AARP", "lowEffort");
	TraitFactory.setMutualExclusive("lowEffort", "youngBuck");
	TraitFactory.setMutualExclusive("lowEffort", "inPrime");
	TraitFactory.setMutualExclusive("itFollows", "pacify");
	TraitFactory.setMutualExclusive("itFollows", "succubus");
	TraitFactory.setMutualExclusive("promiscuous", "Innocent");
	TraitFactory.setMutualExclusive("promiscuous", "swinger");
	TraitFactory.setMutualExclusive("swinger", "Innocent");
	
	TraitFactory.setMutualExclusive("unkempt", "dislikesShowers");
	TraitFactory.setMutualExclusive("unkempt", "neatTidy");
	TraitFactory.setMutualExclusive("unkempt", "lovesClean");
	
	TraitFactory.setMutualExclusive("dislikesShowers", "neatTidy");
	TraitFactory.setMutualExclusive("dislikesShowers", "lovesClean");
	
	TraitFactory.setMutualExclusive("neatTidy", "lovesClean");
	TraitFactory.setMutualExclusive("cute", "Fugly");
	
end

--- Non relevant
initTraits2 = function()
	TraitFactory.addTrait("Conspicuous2", getText("UI_trait_Conspicuous"), 0, getText("UI_trait_ConspicuousDesc"), true);
	TraitFactory.setMutualExclusive("Conspicuous2", "Conspicuous");
	TraitFactory.setMutualExclusive("Conspicuous2", "Inconspicuous");
	
	TraitFactory.addTrait("Desensitized2", getText("UI_trait_Desensitized"), 0, getText("UI_trait_DesensitizedDesc"), true);
	TraitFactory.setMutualExclusive("Desensitized2", "Desensitized");
	TraitFactory.setMutualExclusive("Desensitized2", "Brave");
	TraitFactory.setMutualExclusive("Desensitized2", "Cowardly");
end

------------------------------------------------------------ Professions ------------------------------------------------------------

local function prostituteOccupation()

	local prostitute = ProfessionFactory.addProfession("prostitute", getText("UI_prof_prostitute"), "prof_Prostitute", 2, getText("UI_profdesc_prostitute"));
	prostitute:addXPBoost(Perks.Aiming, 1);
	--prostitute:addXPBoost(Perks.Sprinting, 1);
	prostitute:addFreeTrait("promiscuous");
	prostitute:addFreeTrait("Conspicuous2");

    local profList = ProfessionFactory.getProfessions();
	for i=1,profList:size() do
		local prof = profList:get(i-1);
		BaseGameCharacterDetails.SetProfessionDescription(prof);
	end
end

local function sexSlaveOccupation()

	local sexslave = ProfessionFactory.addProfession("sexslave", getText("UI_prof_sexslave"), "prof_sexslave", -3, getText("UI_profdesc_sexslave"));
	sexslave:addXPBoost(Perks.Strength, -2)
	sexslave:addXPBoost(Perks.Fitness, -2)
	sexslave:addFreeTrait("Desensitized2");
	sexslave:addFreeTrait("dpress");
	
    local profList = ProfessionFactory.getProfessions();
	for i=1,profList:size() do
		local prof = profList:get(i-1);
		BaseGameCharacterDetails.SetProfessionDescription(prof);
	end
end

local function sexperimentOccupation()

	local sexperiment = ProfessionFactory.addProfession("sexperiment", getText("UI_prof_sexperiment"), "prof_sexperiment", 0, getText("UI_profdesc_sexperiment"));
	sexperiment:addFreeTrait("unblessing");
	
    local profList = ProfessionFactory.getProfessions();
	for i=1,profList:size() do
		local prof = profList:get(i-1);
		BaseGameCharacterDetails.SetProfessionDescription(prof);
	end
end

pTraitsInit = function(playernum, character)
	local player = getSpecificPlayer(playernum);
	
	if player:HasTrait("Conspicuous2") then
		player:getTraits():remove("Conspicuous2");
		player:getTraits():add("Conspicuous");
	end	
	
	if player:HasTrait("Desensitized2") then
		player:getTraits():remove("Desensitized2");
		player:getTraits():add("Desensitized");
	end	
	
	if not player:HasTrait("spunkDefault") and not player:HasTrait("AARP") and not player:HasTrait("inPrime") and not player:HasTrait("youngBuck") and not player:HasTrait("lowEffort") then
		player:getTraits():add("spunkDefault");
	end
	
end

function pStartGear(player)
	----------------------------------------------- Occupation ----------------------------------------------- 
	if player:getDescriptor():getProfession() == "prostitute" then
		player:getInventory():AddItem("Base.Revolver", 1);
		--- line# 455 non-table true? ---
		--[[newItem:setCurrentAmmoCount(newItem:getMaxAmmo())
		newItem:setContainsClip(true)
		newItem:setRoundChambered(true)]]
		player:getInventory():AddItem("Base.Bullets45", 1);
		player:getInventory():AddItem("Base.Bullets45", 1);
		player:getInventory():AddItem("Base.Bullets45", 1);
		player:getInventory():AddItem("Base.Bullets45", 1);
		player:getInventory():AddItem("Base.Bullets45", 1);
		player:getInventory():AddItem("Base.Bullets45", 1);
	end
	
	if player:getDescriptor():getProfession() == "sexperiment" then
		local zwinfect = player:getBodyDamage();
		---zwinfect:setInfected(true); always set false, pz has their own calculated logic.
		zwinfect:setInfected(false);
		zwinfect:setInfectionTime(-1);
		zwinfect:setInfectionLevel(25);
	end
	
	----------------------------------------------- Traits -----------------------------------------------
	if player:HasTrait("Rapist") then
		player:getInventory():AddItem("Base.Rope", 1);
		player:getInventory():AddItem("Base.DuctTape", 1);
		player:getInventory():AddItem("Base.KitchenKnife", 1);
	end	
end

--- Hook up event listeners
Events.OnGameBoot.Add(_initTraits);
Events.OnGameBoot.Add(initTraits2);
--[[Events.OnGameBoot.Add(prostituteOccupation);
Events.OnGameBoot.Add(sexSlaveOccupation);
Events.OnGameBoot.Add(sexperimentOccupation);
--- TNT90 ---
Events.OnCreateLivingCharacter.Add(_initTraits);
Events.OnCreateLivingCharacter.Add(initTraits2);
Events.OnCreateLivingCharacter.Add(prostituteOccupation);
Events.OnCreateLivingCharacter.Add(sexSlaveOccupation);
Events.OnCreateLivingCharacter.Add(sexperimentOccupation);]]
--- END ---
Events.OnCreatePlayer.Add(pTraitsInit)

Events.OnNewGame.Add(pStartGear)