diff --git a/Modules/IssixModule/Attacks/IssixSlaveTease.gd b/Modules/IssixModule/Attacks/IssixSlaveTease.gd new file mode 100644 index 0000000..c07b47a --- /dev/null +++ b/Modules/IssixModule/Attacks/IssixSlaveTease.gd @@ -0,0 +1,46 @@ +extends Attack + +func _init(): + id = "IssixSlaveTease" + category = Category.Lust + aiCategory = AICategory.Lust + +func getVisibleName(_context = {}): + return "Collar Tease" + +func getVisibleDesc(_context = {}): + return "Shouldn't see this" + +func _doAttack(_attacker, _receiver, _context = {}): + var text = "" + var lust = 0 + var pain = 0 + if _receiver.getPersonality().getStat(PersonalityStat.Subby) > 0.4: + if(checkDodged(_attacker, _receiver, DamageType.Physical)): + return genericDodgeMessage(_attacker, _receiver, "collar teasing") + lust = RNG.randi_range(40, 60) + text = "{attacker.name} spins around an old slave collar attached to a leash. {receiver.name} observes the collar with {receiver.his} will breaking down wanting to submit." + if(!_receiver.isDefocusing() && _receiver.addEffect(StatusEffect.Weakness, [1])): + text += " {receiver.Name} feels [b]weak[/b]." + else: + if(checkDodged(_attacker, _receiver, DamageType.Physical)): + return genericDodgeMessage(_attacker, _receiver, "collar throw") + text = "{attacker.name} spins around an old slave collar attached to a leash until he changes the direction of swinging to hit {receiver.name} managing to hit {receiver.him} with the bulky collar." + pain = RNG.randi_range(15, 30) + + return { + text = text, + lust = lust, + pain = pain, + } + +func _canUse(_attacker, _receiver, _context = {}): + return !_receiver.isBlindfolded() + +func getAnticipationText(_attacker, _receiver): + var text = "{attacker.name} grabs an old collar from behind and clasps a leash to it." + + return text + +func getRequirements(): + return [AttackRequirement.FreeArms, AttackRequirement.FreeHands, AttackRequirement.CanSee] diff --git a/Modules/IssixModule/Characters/AzazelCharacter.gd b/Modules/IssixModule/Characters/AzazelCharacter.gd new file mode 100644 index 0000000..6af12fc --- /dev/null +++ b/Modules/IssixModule/Characters/AzazelCharacter.gd @@ -0,0 +1,142 @@ +extends Character + +# Incredibly subby and kinky creature, mostly aligns with mod's author preferences.' + +func _init(): + id = "azazel" + npcHasMenstrualCycle = true + npcCharacterType = CharacterType.Inmate + + pickedSkin="AzazelSkin" + pickedSkinRColor=Color("ff464545") + pickedSkinGColor=Color("ff656465") + pickedSkinBColor=Color("ff72005d") + npcSkinData={ + "hair": {"r": Color("ff221310"),"g": Color("ff1f1514"),"b": Color("ff28000c"),}, + "horns": {"r": Color("ffa9a9a9"),"b": Color("ff606060"),}, + } + npcPersonality = { + PersonalityStat.Brat: -0.9, + PersonalityStat.Mean: -1.0, + PersonalityStat.Subby: 1.0, + PersonalityStat.Impatient: 0.1, + PersonalityStat.Naive: 1.0, + PersonalityStat.Coward: 0.7, + } + npcLevel = 8 + npcBasePain = 80 + npcBaseLust = 80 + npcBaseStamina = 80 + npcDefaultFetishInterest = FetishInterest.Neutral + + npcFetishes = { + Fetish.AnalSexReceiving : FetishInterest.Loves, + Fetish.AnalSexGiving : FetishInterest.Hates, + Fetish.VaginalSexGiving : FetishInterest.Hates, + Fetish.VaginalSexReceiving : FetishInterest.Loves, + Fetish.OralSexReceiving : FetishInterest.Likes, + Fetish.Sadism : FetishInterest.ReallyDislikes, + Fetish.Masochism : FetishInterest.Likes, + Fetish.UnconsciousSex : FetishInterest.Hates, + Fetish.Breeding : FetishInterest.Hates, + Fetish.BeingBred : FetishInterest.Loves, + Fetish.Bondage : FetishInterest.Loves, + Fetish.Rigging : FetishInterest.Likes, + Fetish.Condoms : FetishInterest.Dislikes, + Fetish.DrugUse : FetishInterest.Likes, + Fetish.Exhibitionism : FetishInterest.Loves, + Fetish.Tribadism : FetishInterest.Dislikes, + Fetish.StraponSexVaginal : FetishInterest.Dislikes, + Fetish.StraponSexAnal : FetishInterest.SlightlyDislikes, + Fetish.Choking : FetishInterest.SlightlyDislikes, + Fetish.HypnosisSubject : FetishInterest.Loves, + } + npcLustInterests = { + InterestTopic.TallyMarks: Interest.ReallyLikes, + InterestTopic.Bodywritings: Interest.ReallyLikes, + InterestTopic.Gags: Interest.Neutral, + InterestTopic.Blindfolds: Interest.KindaLikes, + InterestTopic.BDSMRestraints: Interest.Loves, + InterestTopic.ButtPlugs: Interest.Neutral, + InterestTopic.VaginalPlugs: Interest.Neutral, + InterestTopic.FeminineBody: Interest.KindaLikes, + InterestTopic.AndroBody: Interest.Loves, + InterestTopic.MasculineBody: Interest.ReallyLikes, + InterestTopic.ThickBody: Interest.Dislikes, + InterestTopic.SlimBody: Interest.Loves, + InterestTopic.BigBreasts: Interest.Hates, + InterestTopic.StuffedPussy: Interest.Likes, + InterestTopic.StuffedPussyOrAss: Interest.KindaLikes, + InterestTopic.Pregnant: Interest.Loves, + InterestTopic.StuffedThroat: Interest.ReallyLikes, + InterestTopic.CoveredInCum: Interest.ReallyLikes, + InterestTopic.CoveredInLotsOfCum: Interest.Loves, + InterestTopic.FullyNaked: Interest.Loves, + InterestTopic.ExposedPussy: Interest.Dislikes, + InterestTopic.ExposedAnus: Interest.ReallyLikes, + InterestTopic.ExposedBreasts: Interest.Hates, + InterestTopic.ExposedCock: Interest.ReallyLikes, + InterestTopic.ExposedPanties: Interest.Neutral, + InterestTopic.ExposedBra: Interest.Neutral, + InterestTopic.LooseAnus: Interest.Neutral, + InterestTopic.LoosePussy: Interest.Neutral, + InterestTopic.TightAnus: Interest.Likes, + InterestTopic.TightPussy: Interest.Likes, + InterestTopic.BigCock: Interest.Hates, + } + +func interestVerbalReaction(interest): + if(interest == InterestTopic.Pregnant): + return "Oh, do you have litter in there? Cuuute, meoowwww!" + if(interest == InterestTopic.Blindfolds): + return "Purrr. How is your hearing? Can you hear me purring from over there?" + +func _getName(): + return "Azazel" + +func getGender(): + return Gender.Male + +func getSmallDescription() -> String: + return "Wears an lilac uniform with number P-655. He is the embodiment of ”meek”." + +func getSpecies(): + return [Species.Feline] + +func getThickness() -> int: + return 0 + +func getFemininity() -> int: + return 67 + +func createBodyparts(): + giveBodypartUnlessSame(GlobalRegistry.createBodypart("felinehead")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("combedbackhair")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("dragonhorns")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("felineears")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("anthrobody")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("anthroarms")) + var breasts = GlobalRegistry.createBodypart("malebreasts") + breasts.size = 0 + giveBodypartUnlessSame(breasts) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("vagina")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("anuswomb")) + var tail = GlobalRegistry.createBodypart("felinetail") + tail.tailScale = 1 + giveBodypartUnlessSame(tail) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("plantilegs")) + skillsHolder.addPerk(Perk.FertilityBroodmother) + skillsHolder.addPerk(Perk.FertilityBetterOvulation) + skillsHolder.addPerk(Perk.FertilityBetterOvulationV2) + skillsHolder.addPerk(Perk.FertilityBetterOvulationV3) + skillsHolder.addPerk(Perk.FertilityDesireToBreed) + skillsHolder.addPerk(Perk.FertilitySubmissiveAndBreedable) + +func onGivingBirth(_impregnatedEggCells: Array, _newkids: Array): + .onGivingBirth(_impregnatedEggCells, _newkids) + +func getBirthWaitTime(): + return 60*60*24*3 + +func getDefaultEquipment(): + return ["inmatecollar", "inmateuniformSexDeviant"] diff --git a/Modules/IssixModule/Characters/HiisiCharacter.gd b/Modules/IssixModule/Characters/HiisiCharacter.gd new file mode 100644 index 0000000..af2917b --- /dev/null +++ b/Modules/IssixModule/Characters/HiisiCharacter.gd @@ -0,0 +1,130 @@ +extends Character + +# Hiisi is a relatively dominating character out of all three pets. He still has some HighSec energy in them + +func _init(): + id = "hiisi" + npcHasMenstrualCycle = false + npcCharacterType = CharacterType.Inmate + + pickedSkin="ArconSkin" + pickedSkinRColor=Color("ffc8c2c2") + pickedSkinGColor=Color("ff423c51") + pickedSkinBColor=Color("ff767676") + npcSkinData={ + "hair": {"r": Color("ffb05745"),"g": Color("ffb05745"),"b": Color("ff2288ab"),}, + "penis": {"r": Color("ff4e2626"),"g": Color("ff9d2121"),"b": Color("ff991a1a"),}, + } + npcPersonality = { + PersonalityStat.Brat: 0.1, + PersonalityStat.Mean: 0.4, + PersonalityStat.Subby: 1.0, + PersonalityStat.Impatient: 0.9, + PersonalityStat.Naive: -1.0, + PersonalityStat.Coward: -0.4, + } + npcLevel = 25 + npcBasePain = 250 + npcBaseLust = 250 + npcBaseStamina = 200 + npcDefaultFetishInterest = FetishInterest.Neutral + npcFetishes = { + Fetish.AnalSexReceiving : FetishInterest.ReallyDislikes, + Fetish.AnalSexGiving : FetishInterest.Likes, + Fetish.VaginalSexGiving : FetishInterest.Likes, + Fetish.OralSexReceiving : FetishInterest.Likes, + Fetish.OralSexGiving : FetishInterest.SlightlyDislikes, + Fetish.Sadism : FetishInterest.Likes, + Fetish.Masochism : FetishInterest.Hates, + Fetish.UnconsciousSex : FetishInterest.Likes, + Fetish.Bondage : FetishInterest.Likes, + Fetish.Rigging : FetishInterest.Likes, + Fetish.Breeding : FetishInterest.Dislikes, + Fetish.Condoms : FetishInterest.Likes, + Fetish.DrugUse : FetishInterest.SlightlyDislikes, + Fetish.Tribadism : FetishInterest.Dislikes, + Fetish.StraponSexVaginal : FetishInterest.Dislikes, + Fetish.StraponSexAnal : FetishInterest.Dislikes, + Fetish.Choking : FetishInterest.Likes, + Fetish.HypnosisSubject : FetishInterest.Hates, + Fetish.HypnosisHypnotist : FetishInterest.Loves + } + npcLustInterests = { + InterestTopic.TallyMarks: Interest.ReallyLikes, + InterestTopic.Bodywritings: Interest.KindaLikes, + InterestTopic.Gags: Interest.Loves, + InterestTopic.Blindfolds: Interest.Loves, + InterestTopic.BDSMRestraints: Interest.Loves, + InterestTopic.ButtPlugs: Interest.Dislikes, + InterestTopic.VaginalPlugs: Interest.Dislikes, + InterestTopic.FeminineBody: Interest.Likes, + InterestTopic.AndroBody: Interest.Likes, + InterestTopic.StuffedPussy: Interest.Likes, + InterestTopic.StuffedPussyOrAss: Interest.KindaLikes, + InterestTopic.StuffedThroat: Interest.Likes, + InterestTopic.CoveredInCum: Interest.Dislikes, + InterestTopic.CoveredInLotsOfCum: Interest.Dislikes, + InterestTopic.FullyNaked: Interest.Likes, + InterestTopic.ExposedPussy: Interest.ReallyLikes, + InterestTopic.ExposedAnus: Interest.ReallyLikes, + InterestTopic.ExposedBreasts: Interest.Likes, + InterestTopic.ExposedCock: Interest.KindaLikes, + InterestTopic.ExposedPanties: Interest.Likes, + InterestTopic.ExposedBra: Interest.Likes, + InterestTopic.TightAnus: Interest.Likes, + InterestTopic.TightPussy: Interest.Likes, + InterestTopic.BigCock: Interest.Hates, + } + +func interestVerbalReaction(interest): + if(interest == InterestTopic.Pregnant): + return "Oh, do you have litter in there? Cuuute, meoowwww!" + if(interest == InterestTopic.Blindfolds): + return "Purrr. How is your hearing? Can you hear me purring from over there?" + +func _getName(): + return "Hiisi" + +func getGender(): + return Gender.Male + +func getSmallDescription() -> String: + return "Wears an red uniform with number P-964." + +func getSpecies(): + return [Species.Canine] + +func getThickness() -> int: + return 23 + +func getFemininity() -> int: + return 0 + +func createBodyparts(): + giveBodypartUnlessSame(GlobalRegistry.createBodypart("anthrobody")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("anthroarms")) + var breasts = GlobalRegistry.createBodypart("malebreasts") + breasts.size = 0 + giveBodypartUnlessSame(breasts) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("caninehead")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("simplehair")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("canineears3")) + var penis = GlobalRegistry.createBodypart("caninepenis") + penis.lengthCM = 10 + penis.ballsScale = 1.2 + giveBodypartUnlessSame(penis) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("anus")) + var tail = GlobalRegistry.createBodypart("huskytail") + tail.tailScale = 1 + giveBodypartUnlessSame(tail) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("digilegs")) + + +func onGivingBirth(_impregnatedEggCells: Array, _newkids: Array): + .onGivingBirth(_impregnatedEggCells, _newkids) + +func getBirthWaitTime(): + return 60*60*24*2 + +func getDefaultEquipment(): + return ["inmatecollar", "inmateuniformHighsec"] diff --git a/Modules/IssixModule/Characters/IssixCharacter.gd b/Modules/IssixModule/Characters/IssixCharacter.gd new file mode 100644 index 0000000..4e0780b --- /dev/null +++ b/Modules/IssixModule/Characters/IssixCharacter.gd @@ -0,0 +1,160 @@ +extends Character + +func _init(): + id = "issix" + npcHasMenstrualCycle = false + npcCharacterType = CharacterType.Inmate + + pickedSkin="HardcoreSkin" + pickedSkinRColor=Color("ffca3030") + pickedSkinGColor=Color("ff720505") + pickedSkinBColor=Color("ff000000") + npcSkinData={ + "head": {"skin": "CunningSkin",}, + "hair": {"r": Color("ffb05745"),"g": Color("ffb05745"),"b": Color("ff2288ab"),}, + "horns": {"r": Color("ffa9a9a9"),}, + "penis": {"g": Color("ffff0000"),"b": Color("ff8b0000"),}, + "legs": {"skin": "SplotchedSkin",}, + } + npcPersonality = { + PersonalityStat.Brat: 0.5, + PersonalityStat.Mean: 1.0, + PersonalityStat.Subby: -1.0, + PersonalityStat.Impatient: 0.1, + PersonalityStat.Naive: -1.0, + PersonalityStat.Coward: -0.7, + } + npcLevel = 50 + npcBasePain = 400 + npcBaseLust = 400 + npcBaseStamina = 500 + npcArmor = { + DamageType.Physical: 15, + DamageType.Lust: 30, + } + npcStats = { + Stat.Strength: 40, + } + npcDefaultFetishInterest = FetishInterest.Neutral + npcFetishes = { + Fetish.AnalSexReceiving : FetishInterest.ReallyDislikes, + Fetish.AnalSexGiving : FetishInterest.Hates, + Fetish.VaginalSexGiving : FetishInterest.Hates, + Fetish.VaginalSexReceiving : FetishInterest.Loves, + Fetish.OralSexReceiving : FetishInterest.Likes, + Fetish.OralSexGiving : FetishInterest.Neutral, + Fetish.Sadism : FetishInterest.ReallyDislikes, + Fetish.Masochism : FetishInterest.Hates, + Fetish.UnconsciousSex : FetishInterest.Loves, + Fetish.BeingBred : FetishInterest.Dislikes, + Fetish.Breeding : FetishInterest.Loves, + Fetish.Bondage : FetishInterest.Likes, + Fetish.Rigging : FetishInterest.Likes, + Fetish.Condoms : FetishInterest.Dislikes, + Fetish.DrugUse : FetishInterest.Likes, + Fetish.Exhibitionism : FetishInterest.Loves, + Fetish.Tribadism : FetishInterest.SlightlyDislikes, + Fetish.StraponSexVaginal : FetishInterest.Dislikes, + Fetish.StraponSexAnal : FetishInterest.SlightlyDislikes, + Fetish.Choking : FetishInterest.SlightlyDislikes, + Fetish.HypnosisSubject : FetishInterest.Loves, + } + npcLustInterests = { + InterestTopic.TallyMarks: Interest.ReallyLikes, + InterestTopic.Bodywritings: Interest.KindaLikes, + InterestTopic.Gags: Interest.Loves, + InterestTopic.Blindfolds: Interest.Loves, + InterestTopic.BDSMRestraints: Interest.Loves, + InterestTopic.ButtPlugs: Interest.Dislikes, + InterestTopic.VaginalPlugs: Interest.Dislikes, + InterestTopic.FeminineBody: Interest.KindaLikes, + InterestTopic.AndroBody: Interest.Likes, + InterestTopic.MasculineBody: Interest.ReallyLikes, + InterestTopic.ThickBody: Interest.Dislikes, + InterestTopic.SlimBody: Interest.Likes, + InterestTopic.BigBreasts: Interest.Hates, + InterestTopic.StuffedPussy: Interest.Likes, + InterestTopic.StuffedPussyOrAss: Interest.KindaLikes, + InterestTopic.Pregnant: Interest.ReallyLikes, + InterestTopic.StuffedThroat: Interest.ReallyLikes, + InterestTopic.CoveredInCum: Interest.ReallyLikes, + InterestTopic.CoveredInLotsOfCum: Interest.Likes, + InterestTopic.FullyNaked: Interest.Loves, + InterestTopic.ExposedPussy: Interest.ReallyLikes, + InterestTopic.ExposedAnus: Interest.ReallyLikes, + InterestTopic.ExposedBreasts: Interest.ReallyLikes, + InterestTopic.ExposedCock: Interest.ReallyLikes, + InterestTopic.ExposedPanties: Interest.Hates, + InterestTopic.ExposedBra: Interest.Hates, + InterestTopic.LooseAnus: Interest.SlightlyDislikes, + InterestTopic.LoosePussy: Interest.SlightlyDislikes, + InterestTopic.TightAnus: Interest.Likes, + InterestTopic.TightPussy: Interest.Likes, + InterestTopic.BigCock: Interest.Hates, + } + +func interestVerbalReaction(interest): + if(interest == InterestTopic.Pregnant): + return "You are much better fit as a common breeder" + if(interest == InterestTopic.Blindfolds): + return "Overconfident much?" + if(interest == InterestTopic.BigCock): + return "Pretty big equipment you got there, have you tried using it?" + if(interest == InterestTopic.SmallCock): + return "Aww, so small. Don't worry, I think it's pretty cute, and as far as reproduction goes, it's pretty telling what your role in it is." + if(interest == InterestTopic.HasVaginaAndCock): + return "Oh wow, your biology blessed you with two? How versatile! Which one you prefer more? Breeder or a stud?" + if(interest == InterestTopic.Bodywritings): + return "I like it when sluts have advertisement all over themselves. Really encourages me to grab that marker." + if(interest == InterestTopic.LactatingBreasts): + return "You produce? Do you think I can have some of that milk for myself?" + +func _getName(): + return "Issix" + +func getGender(): + return Gender.Male + +func _getAttacks(): + return ["IssixSlaveTease", "trygetupattack", "simplepunchattack","CuffPCHands", "ForceGagPC", "ForceMuzzlePC", "simplekickattack", "biteattack", "shoveattack"] + +func getSmallDescription() -> String: + return "Wears a red block uniform with number P-533. He is an intimidating tall demon-dragon, has red fur." + +func getSpecies(): + return [Species.Dragon, Species.Demon] + +func getThickness() -> int: + return 40 + +func getFemininity() -> int: + return 0 + +func createBodyparts(): + giveBodypartUnlessSame(GlobalRegistry.createBodypart("dragonhead")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("combedbackhair")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("dragonears2")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("demonhorns3")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("anthrobody")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("buffarms")) + var breasts = GlobalRegistry.createBodypart("malebreasts") + breasts.size = 0 + giveBodypartUnlessSame(breasts) + var penis = GlobalRegistry.createBodypart("dragonpenis") + penis.lengthCM = 15 + penis.ballsScale = 1 + giveBodypartUnlessSame(penis) + var tail = GlobalRegistry.createBodypart("demontail") + tail.tailScale = 1 + giveBodypartUnlessSame(tail) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("hoofs")) + + +func onGivingBirth(_impregnatedEggCells: Array, _newkids: Array): + .onGivingBirth(_impregnatedEggCells, _newkids) + +func getBirthWaitTime(): + return 60*60*24*10 + +func getDefaultEquipment(): + return ["inmatecollar", "inmateuniform"] diff --git a/Modules/IssixModule/Characters/LamiaCharacter.gd b/Modules/IssixModule/Characters/LamiaCharacter.gd new file mode 100644 index 0000000..7816b13 --- /dev/null +++ b/Modules/IssixModule/Characters/LamiaCharacter.gd @@ -0,0 +1,144 @@ +extends Character + +func _init(): + id = "lamia" + npcHasMenstrualCycle = false + npcCharacterType = CharacterType.Inmate + + pickedSkin="DappledSkin" + pickedSkinRColor=Color("ffca6702") + pickedSkinGColor=Color("ffbb3e03") + pickedSkinBColor=Color("ff9b2226") + npcSkinData={ + "hair": {"r": Color("ff274fb9"),"g": Color("ff243770"),"b": Color("ff3022ab"),}, + "horns": {"r": Color("ff000000"),"g": Color("ff000000"),}, + "penis": {"r": Color("ff2b2a2a"),"g": Color("ff373232"),"b": Color("ff8b0000"),}, + "tail": {"skin": "WildSkin",}, + } + npcPersonality = { + PersonalityStat.Brat: -0.9, + PersonalityStat.Mean: 0.4, + PersonalityStat.Subby: 1.0, + PersonalityStat.Impatient: 0.9, + PersonalityStat.Naive: -1.0, + PersonalityStat.Coward: -0.4, + } + npcDefaultFetishInterest = FetishInterest.Neutral + npcLevel = 20 + npcBasePain = 180 + npcBaseLust = 1000 + npcBaseStamina = 100 + npcArmor = { + DamageType.Lust: 100, + } + + npcFetishes = { + Fetish.AnalSexReceiving : FetishInterest.ReallyDislikes, + Fetish.AnalSexGiving : FetishInterest.Hates, + Fetish.VaginalSexGiving : FetishInterest.Hates, + Fetish.OralSexReceiving : FetishInterest.Dislikes, + Fetish.OralSexGiving : FetishInterest.Dislikes, + Fetish.Sadism : FetishInterest.Hates, + Fetish.Masochism : FetishInterest.Hates, + Fetish.UnconsciousSex : FetishInterest.Hates, + Fetish.Breeding : FetishInterest.Hates, + Fetish.Bondage : FetishInterest.Dislikes, + Fetish.Rigging : FetishInterest.Dislikes, + Fetish.Condoms : FetishInterest.Dislikes, + Fetish.DrugUse : FetishInterest.Dislikes, + Fetish.Exhibitionism : FetishInterest.Dislikes, + Fetish.Tribadism : FetishInterest.SlightlyDislikes, + Fetish.StraponSexVaginal : FetishInterest.Dislikes, + Fetish.StraponSexAnal : FetishInterest.SlightlyDislikes, + Fetish.Choking : FetishInterest.SlightlyDislikes, + Fetish.HypnosisSubject : FetishInterest.Hates, + Fetish.HypnosisHypnotist : FetishInterest.Hates, + } + npcLustInterests = { + InterestTopic.TallyMarks: Interest.Dislikes, + InterestTopic.Bodywritings: Interest.Dislikes, + InterestTopic.Gags: Interest.Dislikes, + InterestTopic.Blindfolds: Interest.Dislikes, + InterestTopic.BDSMRestraints: Interest.Dislikes, + InterestTopic.ButtPlugs: Interest.Dislikes, + InterestTopic.VaginalPlugs: Interest.Dislikes, + InterestTopic.FeminineBody: Interest.KindaLikes, + InterestTopic.AndroBody: Interest.Likes, + InterestTopic.MasculineBody: Interest.ReallyLikes, + InterestTopic.ThickBody: Interest.Dislikes, + InterestTopic.SlimBody: Interest.Dislikes, + InterestTopic.BigBreasts: Interest.Hates, + InterestTopic.StuffedPussy: Interest.Dislikes, + InterestTopic.StuffedPussyOrAss: Interest.Dislikes, + InterestTopic.Pregnant: Interest.Dislikes, + InterestTopic.StuffedThroat: Interest.Dislikes, + InterestTopic.CoveredInCum: Interest.Dislikes, + InterestTopic.CoveredInLotsOfCum: Interest.Dislikes, + InterestTopic.FullyNaked: Interest.Loves, + InterestTopic.ExposedPussy: Interest.ReallyLikes, + InterestTopic.ExposedAnus: Interest.ReallyLikes, + InterestTopic.ExposedBreasts: Interest.ReallyLikes, + InterestTopic.ExposedCock: Interest.ReallyLikes, + InterestTopic.ExposedPanties: Interest.Hates, + InterestTopic.ExposedBra: Interest.Hates, + InterestTopic.LooseAnus: Interest.Dislikes, + InterestTopic.LoosePussy: Interest.Dislikes, + InterestTopic.TightAnus: Interest.Dislikes, + InterestTopic.TightPussy: Interest.Dislikes, + InterestTopic.BigCock: Interest.Hates, + } + +func interestVerbalReaction(interest): + if(interest == InterestTopic.Pregnant): + return "Oh, do you have litter in there? Cuuute, meoowwww!" + if(interest == InterestTopic.Blindfolds): + return "Purrr. How is your hearing? Can you hear me purring from over there?" + +func _getName(): + return "Lamia" + +func getGender(): + return Gender.Male + +func getSmallDescription() -> String: + return "Wears an orange uniform with number P-790." + +func getSpecies(): + return [Species.Canine] # if in the future foxes are introduced, the character is canonically a fox + +func onGivingBirth(_impregnatedEggCells: Array, _newkids: Array): + .onGivingBirth(_impregnatedEggCells, _newkids) + +func getBirthWaitTime(): + return 60*60*24*2 + +func getDefaultEquipment(): + return ["inmatecollar", "inmateuniform"] + +func getThickness() -> int: + return 70 + +func getFemininity() -> int: + return 20 + +func createBodyparts(): + giveBodypartUnlessSame(GlobalRegistry.createBodypart("anthrobody")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("anthroarms")) + var breasts = GlobalRegistry.createBodypart("malebreasts") + breasts.size = 0 + giveBodypartUnlessSame(breasts) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("foxhead")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("messyhair2")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("fennecears")) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("dragonhorns")) + var penis = GlobalRegistry.createBodypart("felinepenis") + penis.lengthCM = 15 + penis.ballsScale = 1 + giveBodypartUnlessSame(penis) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("anuswomb")) + var tail = GlobalRegistry.createBodypart("foxtail") + tail.tailScale = 0.5 + giveBodypartUnlessSame(tail) + giveBodypartUnlessSame(GlobalRegistry.createBodypart("digilegs")) + skillsHolder.addPerk(Perk.StartInfertile) + skillsHolder.addPerk(Perk.StartNoHeat) diff --git a/Modules/IssixModule/Events/CornerPriorityEvent.gd b/Modules/IssixModule/Events/CornerPriorityEvent.gd new file mode 100644 index 0000000..165ea45 --- /dev/null +++ b/Modules/IssixModule/Events/CornerPriorityEvent.gd @@ -0,0 +1,60 @@ +extends EventBase + +func _init(): + id = "IssixSpecialEvent" + + +var registered_special_scenes = [['IssixSlaveryIntroCont', 1, {}], ['IssixBringsComicbooks', 2, {"Comic_Books": 1}], ['IssixSlaveryBowlTraing', 2, {}], ['IssixSlaveryBranding', 3, {}]] + +class CustomSorter: + static func sort_by_progressionpoints(a, b): + if a[1] < b[1]: + return true + return false + +func checkRequirements(requirements: Dictionary): + for key in requirements.keys(): + if requirements[key] is int or requirements[key] is float: + if getModuleFlag("IssixModule", key, 0) < requirements[key]: + return false + elif requirements[key] is String: + if getModuleFlag("IssixModule", key, 0) != requirements[key]: + return false + return true + +func shouldBeShownForcedEvent(): + var scenes_seen = getModuleFlag("IssixModule", "Misc_Slavery_Info", {"scenes_seen": []}) + var current_progression_points = GM.main.getModuleFlag("IssixModule", "Progression_Points", 1) + if GM.main.getDays() >= GM.main.getModuleFlag("IssixModule", "Progression_Day_Next", 0) and GM.main.getModuleFlag("IssixModule", "Unwelcome_At_Corner", false) != true: + registered_special_scenes.sort_custom(CustomSorter, "sort_by_progressionpoints") + for scene in registered_special_scenes: + if scene[1] > current_progression_points: + return null + if scenes_seen["scenes_seen"].find(scene[0]) == -1 and checkRequirements(scene[2]): + return scene[0] + return null + +func registerTriggers(es): + es.addTrigger(self, Trigger.EnteringRoom, "hall_ne_corner") + +func react(_triggerID, _args): + #if(doEventCheck("IssixBusy") != null): + # return false + var scene_to_show = shouldBeShownForcedEvent() + if scene_to_show != null: + runScene(scene_to_show) + return true + return false + + +func getPriority(): + return 20 + +# func onButton(_method, _args): +# if(_method == "talk"): +# runScene("IssixTalkScene") +# if(_method == "pets"): +# runScene("PetsTalkScene") +# if(_method == "paper"): +# runScene("NoPetsTalkScene") +# diff --git a/Modules/IssixModule/Events/EngRoomClosetEvent.gd b/Modules/IssixModule/Events/EngRoomClosetEvent.gd new file mode 100644 index 0000000..aef4086 --- /dev/null +++ b/Modules/IssixModule/Events/EngRoomClosetEvent.gd @@ -0,0 +1,26 @@ +extends EventBase + +func _init(): + id = "EngRoomClosetEvent" + +func registerTriggers(es): + es.addTrigger(self, Trigger.EnteringRoom, "eng_corridor6") + +func run(_triggerID, _args): + var quest_status = getModuleFlag("IssixModule", "Quest_Status") + if(3 > quest_status and quest_status > 0): # In the future potentially make it possible to be a daily event thing + if(GM.pc.isBlindfolded()): + if getModuleFlag("IssixModule", "Quest_Status") == 1: + addButton("Issix's Task", "Is it time?", "wall") + else: + addButton("Closet", "Time to get that thing", "wall") + elif quest_status > 2: + addDisabledButton("Closet", "This place is of no significance to you anymore") + +func getPriority(): + return 0 + +func onButton(_method, _args): + if(_method == "wall"): + runScene("EngRoomScene") + diff --git a/Modules/IssixModule/Events/EventTileOnEnter.gd b/Modules/IssixModule/Events/EventTileOnEnter.gd new file mode 100644 index 0000000..7ccb4d1 --- /dev/null +++ b/Modules/IssixModule/Events/EventTileOnEnter.gd @@ -0,0 +1,73 @@ +extends EventBase + +func _init(): + id = "IssixEvent" + +func registerTriggers(es): + es.addTrigger(self, Trigger.EnteringRoom, "hall_ne_corner") + es.addEventCheck(self, "IssixBusy") + +func run(_triggerID, _args): + #if(doEventCheck("IssixBusy") != null): + # return false + if(GM.main.isVeryLate()): # Add something in the nightime it's very late? + saynn("You see an empty chair in the corner with three blankets laying around.") + return false + + if(!getModuleFlag("IssixModule", "Issix_Introduced")): # Do that if not night + saynn("You see a demon-dragon sitting on a chair in a corner, around him there are three leashed creatures.") + GM.main.setModuleFlag("IssixModule", "Score_Explored", 0) # is there a better place to do this? + GM.main.setModuleFlag("IssixModule", "Quest_Status", 0) + addButton("Demon", "Talk to the demon-dragon", "talk") + return + + GM.main.applyWorldEdit("IssixWorldEdit") + + if(checkCharacterBusy("IssixBusy", "Issix is not here", "Issix")): + saynn("This corner is not occupied by anyone at the moment, just three empty blankets with a chair.") + if getModuleFlag("IssixModule", "Quest_Status") == 5: + addButton("Paper", "A piece of paper lies left in a hurry", "paper") + return + + var player_enslaved = getModuleFlag("IssixModule", "PC_Enslavement_Role", 0) + if player_enslaved > 0: + if getModuleFlag("IssixModule", "Unwelcome_At_Corner", false) != true: + saynn("You see your Master sitting on his chair in the corner, around him there is Azazel, Hiisi and Lamia.") + addButton("Master", "Talk to Master Issix", "talk") + addButton("Pets", "Look at Master's pets", "pets") + match player_enslaved: + 1.0: # WHY ARE NUMBER FLAGS FLOATS ASDJASODHASUDHASIDHBASHDASHDOASDJASD kill me + addButton("Pet tasks", "Get a read on today's pet tasks", "slavery") + 2.0: + addButton("Prostitution", "Open prostitution info", "slavery") + _: + saynn(player_enslaved) + else: + addDisabledButton("Master", "He doesn't want to speak to you today") + addDisabledButton("Pets", "They don't want to speak to you today") + else: + saynn("You see Issix sitting on a chair in a corner, around him there are three leashed slaves.") + addButton("Issix", "Talk to Issix", "talk") + if(!getModuleFlag("IssixModule", "Pets_Introduced")): + #addButton("Look at pets", "Look at pets", "pets") + addDisabledButton("Talk with pets", "You should probably first talk with intimidating figure who got them leashed") + else: + addButton("Pets", "Look at pets", "pets") + + +func getPriority(): + return 0 + +func onButton(_method, _args): + if(_method == "talk"): + runScene("IssixTalkScene") + if(_method == "pets"): + runScene("PetsTalkScene") + if(_method == "paper"): + runScene("NoPetsTalkScene") + if _method == "slavery": + runScene("SlaveryInfoScreen") + +func eventCheck(_checkID, _args = []): + if(getModuleFlag("IssixModule", "Quest_Status") == 5 and getModuleFlag("IssixModule", "Quest_Wait_Another_Day") == true): + return {busy=true} diff --git a/Modules/IssixModule/Events/GreenhouseCatnipEvent.gd b/Modules/IssixModule/Events/GreenhouseCatnipEvent.gd new file mode 100644 index 0000000..7512e2a --- /dev/null +++ b/Modules/IssixModule/Events/GreenhouseCatnipEvent.gd @@ -0,0 +1,29 @@ +extends EventBase + +func _init(): + id = "AzazelCatnipEvent" + +func registerTriggers(es): + es.addTrigger(self, Trigger.EnteringRoom, "main_green_corridor9") + +func run(_triggerID, _args): + if(GM.main.getModuleFlag("IssixModule", "Azazel_Catnip_noticed", false) == false): + if "feline" in GM.pc.getSpecies(): + saynn("You approach greenhouses, each one looks like a huge long tent with lots of artificial lights inside. Your sensitive nose catches a whiff of a peculiar smell coming from one of the greenhouses, something very primal to your very instincts...") + addButton("Investigate", "Find the source of smell", "greenhouse") + elif RNG.chance(50): + saynn("While minding your business you notice a sign which depicts a crossed out feline. This strikes you as very odd, why would felines be banned from what appears to be a single greenhouse?") + addButton("Investigate", "Try to find out what's up?", "greenhouse") + else: + saynn("While going through the greenhouses you remember a familiar greenhouse that had catnip in it. You could try and get some for yourself, or someone else.") + if(!GM.main.getModuleFlag("IssixModule", "Azazel_Catnip_taken_today")): + addButtonUnlessLate("Steal", "Try and steal something", "greenhouse") + else: + addDisabledButton("Steal", "Too dangerous to do this again today") + +func getPriority(): + return 0 + +func onButton(_method, _args): + if(_method == "greenhouse"): + runScene("GreenhouseCatnip") diff --git a/Modules/IssixModule/Events/IssixQuestionnaireEvent.gd b/Modules/IssixModule/Events/IssixQuestionnaireEvent.gd new file mode 100644 index 0000000..a8c605c --- /dev/null +++ b/Modules/IssixModule/Events/IssixQuestionnaireEvent.gd @@ -0,0 +1,27 @@ +extends EventBase + +func _init(): + id = "Ch1IssixQuestQuestionnaire" + +func registerTriggers(es): + es.addTrigger(self, Trigger.TalkingToNPC, "issix") + +func run(_triggerID, _args): + if(GM.main.getModuleFlag("IssixModule", "Quest_Status") == 4): + if GM.main.getModuleFlag("IssixModule", "Quest_Wait_Another_Day") == false: + addButton("Next task", "Ask Issix about next task", "main") + else: + addDisabledButton("Next task", "You need to wait until tomorrow") + return true + elif(GM.main.getModuleFlag("IssixModule", "Quest_Status") == 5): + addButton("Questionnaire", "Ask Issix about continuing the questionnaire", "main") + return false + + +func onButton(_method, _args): + if(_method == "main"): + GM.main.endCurrentScene() + runScene("IssixQuestionnaire") + +func getPriority(): + return 20 diff --git a/Modules/IssixModule/Events/IssixRegularSearch.gd b/Modules/IssixModule/Events/IssixRegularSearch.gd new file mode 100644 index 0000000..0a9b2d4 --- /dev/null +++ b/Modules/IssixModule/Events/IssixRegularSearch.gd @@ -0,0 +1,19 @@ +extends EventBase + +func _init(): + id = "IssixSearchEvent" + +func registerTriggers(es): + es.addTrigger(self, Trigger.EnteringRoom, "hall_mainentrance") + +func react(_triggerID, _args): + if(doEventCheck("IssixBusy") != null) or GM.main.isVeryLate(): + return false + + var visited = GM.main.getModuleFlag("IssixModule", "Last_Day_Visited_Master") + if visited != null and GM.main.getDays() > visited + 2: # 3 days without visiting master + runScene("IssixFoundPlayer") + + +func getPriority(): + return 10 diff --git a/Modules/IssixModule/Events/MedicalPeekEvent.gd b/Modules/IssixModule/Events/MedicalPeekEvent.gd new file mode 100644 index 0000000..c4ee032 --- /dev/null +++ b/Modules/IssixModule/Events/MedicalPeekEvent.gd @@ -0,0 +1,28 @@ +extends EventBase + +func _init(): + id = "MedicalLamiaPeekEvent" + +func registerTriggers(es): + es.addTrigger(self, Trigger.EnteringRoom, "med_near_wards") + es.addEventCheck(self, "ElizaBusy") + +func react(_triggerID, _args): + if(getModuleFlag("IssixModule", "Quest_Status") == 5 and getModuleFlag("IssixModule", "Quest_Wait_Another_Day") == true): + runScene("MedicalLamiaPeekScene") + return true + # I don't have any other way of preventing the player from entering the medical room so we do some forcy scene on them, they would never see that coming! + #addButton("Investigate", "Eavesdrop on large commotion in the hospital room next to you", "main") + + return false + +func getPriority(): + return 150 + +func onButton(_method, _args): + if(_method == "main"): + runScene("MedicalLamiaPeekScene") + +func eventCheck(_checkID, _args = []): # sorry player, you can't heal, Eliza is occupied by Issix's pet + if(_checkID == "ElizaBusy" and getModuleFlag("IssixModule", "Quest_Status") == 5 and getModuleFlag("IssixModule", "Quest_Wait_Another_Day") == true): + return {busy=true} diff --git a/Modules/IssixModule/Events/Overwrites/BullyGangEvent.gd b/Modules/IssixModule/Events/Overwrites/BullyGangEvent.gd new file mode 100644 index 0000000..b3a5ff0 --- /dev/null +++ b/Modules/IssixModule/Events/Overwrites/BullyGangEvent.gd @@ -0,0 +1,25 @@ +extends EventBase + +func _init(): + id = "BullyGangEvent" + +func registerTriggers(es): + es.addTrigger(self, Trigger.ApproachedYogaMats) + es.addTrigger(self, Trigger.ApproachedWeightsBench) + +func react(_triggerID, _args): + if(getModuleFlag("GymModule", "Gym_BullyGangPayed")): + return false + + if getModuleFlag("IssixModule", "Gym_Bullies_Left_Alone", false) == true: + return false + + if(RNG.chance(50)): + return false + + runScene("BullyGangScene") + setModuleFlag("GymModule", "Gym_BullyGangPayed", true) + return true + +func getPriority(): + return 20 diff --git a/Modules/IssixModule/Events/PetWalkExamEvent.gd b/Modules/IssixModule/Events/PetWalkExamEvent.gd new file mode 100644 index 0000000..4bc32a9 --- /dev/null +++ b/Modules/IssixModule/Events/PetWalkExamEvent.gd @@ -0,0 +1,25 @@ +extends EventBase + +func _init(): + id = "Ch1IssixQuestWalk" + +func registerTriggers(es): + es.addTrigger(self, Trigger.TalkingToNPC, "issix") + +func run(_triggerID, _args): + if(GM.main.getModuleFlag("IssixModule", "Quest_Status") == 6): + if GM.main.getModuleFlag("IssixModule", "Quest_Wait_Another_Day") == false: + addButton("Next task", "Ask Issix about next task", "main") + else: + addDisabledButton("Next task", "You need to wait until tomorrow") + return true + return false + + +func onButton(_method, _args): + if(_method == "main"): + GM.main.endCurrentScene() + runScene("IssixPetWalk") + +func getPriority(): + return 20 diff --git a/Modules/IssixModule/Events/PlayerCellModifierEvent.gd b/Modules/IssixModule/Events/PlayerCellModifierEvent.gd new file mode 100644 index 0000000..e3179d9 --- /dev/null +++ b/Modules/IssixModule/Events/PlayerCellModifierEvent.gd @@ -0,0 +1,22 @@ +extends EventBase + +func _init(): + id = "ArtworkModifyingPlayerCell" + +func registerTriggers(es): + es.addTrigger(self, Trigger.EnteringPlayerCell) + +func run(_triggerID, _args): + if getModuleFlag("IssixModule", "Placed_Portrait_In_Cell", false): + saynn("On the wall you can see a vertical sheet of paper with your face holding a cookie in the mouth. Drawn by Lamia.") + return + + if getModuleFlag("IssixModule", "Received_Portrait_From_Lamia", false) and getModuleFlag("IssixModule", "Placed_Portrait_In_Cell") == null: + addButton("Portrait", "You can choose to put a portrait you've received from Lamia on the wall of your cell", "portrait") + +func onButton(_method, _args): + if(_method == "portrait"): + runScene("PlayerCellLamiaPortraitScene") + +func getPriority(): + return 11 diff --git a/Modules/IssixModule/Events/SlaveryIntroEvent.gd b/Modules/IssixModule/Events/SlaveryIntroEvent.gd new file mode 100644 index 0000000..c3b7297 --- /dev/null +++ b/Modules/IssixModule/Events/SlaveryIntroEvent.gd @@ -0,0 +1,25 @@ +extends EventBase + +func _init(): + id = "Ch2IssixSlaveryIntro" + +func registerTriggers(es): + es.addTrigger(self, Trigger.TalkingToNPC, "issix") + +func run(_triggerID, _args): + if(GM.main.getModuleFlag("IssixModule", "Quest_Status") == 7): + if GM.main.getModuleFlag("IssixModule", "Quest_Wait_Another_Day") == false: + addButton("Do it", "Ask Issix about becoming his pet", "main") + else: + addDisabledButton("Slavery", "You need to wait until tomorrow before you can ask Issix about becomin his slave") + return true + return false + + +func onButton(_method, _args): + if(_method == "main"): + GM.main.endCurrentScene() + runScene("IssixSlaveryIntro") + +func getPriority(): + return 20 diff --git a/Modules/IssixModule/Floors/Closet.gd b/Modules/IssixModule/Floors/Closet.gd new file mode 100644 index 0000000..3d98ece --- /dev/null +++ b/Modules/IssixModule/Floors/Closet.gd @@ -0,0 +1,12 @@ +extends SubGameWorld + + + +func _on_Closet_onEnter(room): + room.addButton("Leave", "Leave the closet", "leave") + + +func _on_Closet_onReact(_room, key): + if(key == "leave"): + GM.pc.setLocation("med_lobbynw") + GM.main.reRun() diff --git a/Modules/IssixModule/Floors/Closet.tscn b/Modules/IssixModule/Floors/Closet.tscn new file mode 100644 index 0000000..3abd313 --- /dev/null +++ b/Modules/IssixModule/Floors/Closet.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://Game/World/SubWorld.tscn" type="PackedScene" id=1] +[ext_resource path="res://Game/World/GameRoom.tscn" type="PackedScene" id=2] +[ext_resource path="res://Modules/IssixModule/Floors/Closet.gd" type="Script" id=3] + +[node name="Closet" instance=ExtResource( 1 )] +script = ExtResource( 3 ) + +[node name="Closet" parent="." index="0" groups=["zone_poi"] instance=ExtResource( 2 )] +self_modulate = Color( 0.7, 0.7, 1, 1 ) +position = Vector2( 192, 256 ) +__meta__ = { +"_editor_description_": "meow" +} +roomName = "Closet" +roomID = "eng_closet" +roomDescription = "This very claustrophobic room is illuminated by a single light bulb hanging from the top, seems like this room was spared from the newer technology present everywhere else in the prison. +The room has at least 5 large file cabinets, 2 shelves and a trash can in the corner. All of the drawers except one seem to have a number attached to them. There is only one entrance, the doors on the west side of the room. Walls of the rooms are behind the cabinets." +blindRoomDescription = "The atmosphere of the place you are in, changed from the large hallway to something a lot smaller. Sounds don't spread as they did in hallway before you entered. It's probably one of the quietest places you've been in." +roomColor = 3 +loctag_Offlimits = true + +[connection signal="onEnter" from="Closet" to="." method="_on_Closet_onEnter"] +[connection signal="onReact" from="Closet" to="." method="_on_Closet_onReact"] diff --git a/Modules/IssixModule/InterestTopics/IssixTopics.gd b/Modules/IssixModule/InterestTopics/IssixTopics.gd new file mode 100644 index 0000000..5806f5d --- /dev/null +++ b/Modules/IssixModule/InterestTopics/IssixTopics.gd @@ -0,0 +1,27 @@ +extends TopicBase + +func _init(): + handles_ids = [ + "IssixBrand" + ] + +func getTopicValue(_topicID, _pc): + if(_topicID == "IssixBrand"): + if(GM.main.getModuleFlag("IssixModule", "Issix_Branded_PC") == true): + return 1.0 + + return 0.0 + +func getVisibleName(_topicID): + if(_topicID == "IssixBrand"): + return "Issix's brand" + + + return "error:"+str(_topicID) + +func getAddsToFocus(_topicID, _focus) -> float: + if(_topicID == "IssixBrand"): + if(_focus == LustFocus.Butt): + return 1.0 + + return 0.0 diff --git a/Modules/IssixModule/IssixPetQuest.gd b/Modules/IssixModule/IssixPetQuest.gd new file mode 100644 index 0000000..edef44d --- /dev/null +++ b/Modules/IssixModule/IssixPetQuest.gd @@ -0,0 +1,59 @@ +extends QuestBase + +func _init(): + id = "IssixsPetQuest" + +func getVisibleName(): + return "Becoming something lesser" + +func getProgress(): + var quest_status = GM.main.getModuleFlag("IssixModule", "Quest_Status") + var quest_await = GM.main.getModuleFlag("IssixModule", "Quest_Wait_Another_Day", false) + var quest_rejection = GM.main.getModuleFlag("IssixModule", "Quest_Rejected_By_Issix", 0) + var result = [] + if quest_rejection == 1 or quest_rejection == 4: + return ["You rejected Issix's offer to become his pet."] + result.append("Issix gave you a map and a task - to get him whatever is in a place marked on the map, and look for number 84. Apparently this trust exercise requires you to wear a blindfold, wonder why...") + if(quest_status > 1): + result.append("You've found the hidden closet. Now just to find what Issix asked of you...") + if(quest_status > 2): + result.append("You've got a pack of gum. Return it to Issix.") + if(quest_status > 4): + result.append("You've delivered a pack of gum to Issix. His next request was of you to complete a ”test” of some sorts.") + if(quest_status == 3 and quest_await): + result.append("You've delivered a pack of gum to Issix. He has asked you to wait until tomorrow when he will have next task for you") + if(quest_status == 3 and !quest_await): + result.append("You've delivered a pack of gum to Issix. He should have a new task for you today.") + if(quest_status > 5 and quest_rejection == 0): + result.append("You've finished the questionnaire which you've passed. Issix asked you to come back the next day for last trial.") + if(quest_status == 5 and quest_await): + result.append("You started the questionnaire, however your answering session was abruptly interrupted by medical emergency of Lamia. Issix asked you to come other day.") + if(quest_status == 5 and !quest_await): + result.append("You started the questionnaire, however your answering session was abruptly interrupted by medical emergency of Lamia. Issix asked you to come other day, at least a day has passed so you should check up with them.") + if quest_status > 6 and quest_rejection == 0: + result.append("You've succeeded Issix's last trial and have gotten permission to become Issix's pet. Issix said that your introduction is the next day,") + if quest_status > 8: + result.append("Issix has became your new Master as you've given into him as his "+("pet" if GM.main.getModuleFlag("IssixModule", "PC_Enslavement_Role", 1) == 1 else "prostitute")+".") + if(quest_rejection > 1): + result.append("Issix rejected the idea of you being his pet after you failed his test.") + return result + +func isVisible(): + return GM.main.getModuleFlag("IssixModule", "Quest_Status") > 0 + +func isCompleted(): + return GM.main.getModuleFlag("IssixModule", "Quest_Status") > 10 or GM.main.getModuleFlag("IssixModule", "Quest_Rejected_By_Issix", 0) > 1 + +func isMainQuest(): + return false + +# quest_status - state (number) +# 0 - no quest/haven't started +# -1 - refused Issixs quest +# 1 - accepted Issixs quest +# 2 - arrived at closet +# 3 - looted the gumball +# 4 - gave the gumball to Issix +# 5 - answered first part of questionnaire +# 6 - answered second part of questionnaire, waits for the walk +# 7 - got accepted as a pet diff --git a/Modules/IssixModule/IssixWorldEdit.gd b/Modules/IssixModule/IssixWorldEdit.gd new file mode 100644 index 0000000..e5de5a8 --- /dev/null +++ b/Modules/IssixModule/IssixWorldEdit.gd @@ -0,0 +1,8 @@ +extends WorldEditBase + +func _init(): + id = "IssixWorldEdit" + +func apply(world: GameWorld): + if(getFlag("IssixModule.Issix_Introduced")): + world.setRoomSprite("hall_ne_corner", RoomStuff.RoomSprite.PERSON) diff --git a/Modules/IssixModule/Items/CatnipItem.gd b/Modules/IssixModule/Items/CatnipItem.gd new file mode 100644 index 0000000..cfafa1e --- /dev/null +++ b/Modules/IssixModule/Items/CatnipItem.gd @@ -0,0 +1,67 @@ +extends ItemBase + +func _init(): + id = "CatnipPlant" + +func getVisibleName(): + return "Catnip" + +func getDescription(): + return "An enticing plant for most of felines. Used as harmfull drug, unless in large quantities. Can have effects on a feline if consumed." + +func isFeline(character:BaseCharacter): + return "feline" in character.getSpecies() + +func canUseInCombat(): + return isFeline(GM.pc) + +func useInCombat(_attacker:Character, _receiver): + if(isFeline(_attacker)): + if(!(_attacker.isPlayer() and GM.main.getFlag("HypnokinkModule.SoftOptIn") == false)): + _attacker.addEffect(StatusEffect.UnderHypnosis) + _attacker.addLust(10) + removeXOrDestroy(1) + return _attacker.getName() + " ate a catnip plant! That feels... Wahhaa." + else: + removeXOrDestroy(1) + return _attacker.getName() + " ate a catnip plant! It didn't have any effect." + +func getPossibleActions(): + if(isFeline(GM.pc)): # We really shouldn't assume the item is being used by a player character, but sadly game does not give us context for the item user :( + return [ + { + "name": "Eat one!", + "scene": "UseItemLikeInCombatScene", + "description": "Eat the catnip", + }, + ] + else: + return [] + +func getPrice(): + return 0 + +func canSell(): + return true + +func canCombine(): + return true + +func tryCombine(_otherItem): + return .tryCombine(_otherItem) + +func getTags(): + return [] + +func getItemCategory(): + return ItemCategory.Medical + +func saveData(): + var data = .saveData() + return data + +func loadData(data): + .loadData(data) + +func getInventoryImage(): + return "res://Modules/IssixModule/Items/Icons/catnip.png" diff --git a/Modules/IssixModule/Items/ClosetMap.gd b/Modules/IssixModule/Items/ClosetMap.gd new file mode 100644 index 0000000..f770352 --- /dev/null +++ b/Modules/IssixModule/Items/ClosetMap.gd @@ -0,0 +1,62 @@ +extends ItemBase + +func _init(): + id = "IssixsMap" + +func getVisibleName(): + return "Issix's Map" + +func getDescription(): + return "A map showing directinons" + +func canUseInCombat(): + return false + +func useInCombat(_attacker:Character, _receiver): + return "Map shows the following:\n\n[font=res://Fonts/smallconsolefont.tres]"+Util.readFile("res://Modules/IssixModule/Misc/asciimapsmall.txt")+"[/font]" + +func getPossibleActions(): + if(true): # We really shouldn't assume the item is being used by a player character, but sadly game does not give us context for the item user :( + return [ + { + "name": "Look", + "scene": "UseItemLikeInCombatScene", + "description": "Look at the map", + }, + ] + else: + return [ + { + "name": "Discard", + "scene": "UseItemLikeInCombatScene", + "description": "Discard this map, it won't be useful to you anymore.", + }, + ] + +func getPrice(): + return 0 + +func canSell(): + return false + +func canCombine(): + return false + +func tryCombine(_otherItem): + return .tryCombine(_otherItem) + +func getTags(): + return [] + +func getItemCategory(): + return ItemCategory.Generic + +func saveData(): + var data = .saveData() + return data + +func loadData(data): + .loadData(data) + +func getInventoryImage(): + return "res://Modules/IssixModule/Items/Icons/issixsmap.png" diff --git a/Modules/IssixModule/Items/CookieItem.gd b/Modules/IssixModule/Items/CookieItem.gd new file mode 100644 index 0000000..c703fde --- /dev/null +++ b/Modules/IssixModule/Items/CookieItem.gd @@ -0,0 +1,55 @@ +extends ItemBase + +func _init(): + id = "Cookie" + +func getVisibleName(): + return "Cookie" + +func getDescription(): + return "A regular cookie, has brown chocolate chips on it." + +func canUseInCombat(): + return true + +func useInCombat(_attacker:Character, _receiver): + _attacker.addStamina(15) + removeXOrDestroy(1) + return _attacker.getName() + " ate a cookie. They feel a little bit more full." + +func getPossibleActions(): # We really shouldn't assume the item is being used by a player character, but sadly game does not give us context for the item user :( + return [ + { + "name": "Eat one!", + "scene": "UseItemLikeInCombatScene", + "description": "Eat the cookie", + }, + ] + +func getPrice(): + return 0 + +func canSell(): + return true + +func canCombine(): + return true + +func tryCombine(_otherItem): + return .tryCombine(_otherItem) + +func getTags(): + return [] + +func getItemCategory(): + return ItemCategory.Generic + +func saveData(): + var data = .saveData() + return data + +func loadData(data): + .loadData(data) + +func getInventoryImage(): + return "res://Modules/IssixModule/Items/Icons/cookie.png" diff --git a/Modules/IssixModule/Items/Icons/catnip.png b/Modules/IssixModule/Items/Icons/catnip.png new file mode 100644 index 0000000..fac71d8 Binary files /dev/null and b/Modules/IssixModule/Items/Icons/catnip.png differ diff --git a/Modules/IssixModule/Items/Icons/catnip.png.import b/Modules/IssixModule/Items/Icons/catnip.png.import new file mode 100644 index 0000000..6051791 --- /dev/null +++ b/Modules/IssixModule/Items/Icons/catnip.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/catnip.png-13dd8fa59071100df582cb0019f4a872.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Modules/IssixModule/Items/Icons/catnip.png" +dest_files=[ "res://.import/catnip.png-13dd8fa59071100df582cb0019f4a872.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=0 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/Modules/IssixModule/Items/Icons/cookie.png b/Modules/IssixModule/Items/Icons/cookie.png new file mode 100644 index 0000000..2506b9f Binary files /dev/null and b/Modules/IssixModule/Items/Icons/cookie.png differ diff --git a/Modules/IssixModule/Items/Icons/cookie.png.import b/Modules/IssixModule/Items/Icons/cookie.png.import new file mode 100644 index 0000000..070034e --- /dev/null +++ b/Modules/IssixModule/Items/Icons/cookie.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/cookie.png-f1fa6ed634f5e8bfb60119807c8f2242.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Modules/IssixModule/Items/Icons/cookie.png" +dest_files=[ "res://.import/cookie.png-f1fa6ed634f5e8bfb60119807c8f2242.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=0 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/Modules/IssixModule/Items/Icons/issixsmap.png b/Modules/IssixModule/Items/Icons/issixsmap.png new file mode 100644 index 0000000..292acf7 Binary files /dev/null and b/Modules/IssixModule/Items/Icons/issixsmap.png differ diff --git a/Modules/IssixModule/Items/Icons/issixsmap.png.import b/Modules/IssixModule/Items/Icons/issixsmap.png.import new file mode 100644 index 0000000..5cccd6f --- /dev/null +++ b/Modules/IssixModule/Items/Icons/issixsmap.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/issixsmap.png-60f60f2134d573028bb0fd9dd4d9a13e.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Modules/IssixModule/Items/Icons/issixsmap.png" +dest_files=[ "res://.import/issixsmap.png-60f60f2134d573028bb0fd9dd4d9a13e.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=0 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/Modules/IssixModule/Items/catnip.png b/Modules/IssixModule/Items/catnip.png new file mode 100644 index 0000000..fac71d8 Binary files /dev/null and b/Modules/IssixModule/Items/catnip.png differ diff --git a/Modules/IssixModule/Items/catnip.png.import b/Modules/IssixModule/Items/catnip.png.import new file mode 100644 index 0000000..b5ed911 --- /dev/null +++ b/Modules/IssixModule/Items/catnip.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/catnip.png-225c9de9d66fa9225bcc1239ca3cabf0.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Modules/IssixModule/Items/catnip.png" +dest_files=[ "res://.import/catnip.png-225c9de9d66fa9225bcc1239ca3cabf0.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=0 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/Modules/IssixModule/Items/cookie.png b/Modules/IssixModule/Items/cookie.png new file mode 100644 index 0000000..2506b9f Binary files /dev/null and b/Modules/IssixModule/Items/cookie.png differ diff --git a/Modules/IssixModule/Items/cookie.png.import b/Modules/IssixModule/Items/cookie.png.import new file mode 100644 index 0000000..1b20d09 --- /dev/null +++ b/Modules/IssixModule/Items/cookie.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/cookie.png-bc8b9cb3712e5314bb44b4aeb129e69d.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Modules/IssixModule/Items/cookie.png" +dest_files=[ "res://.import/cookie.png-bc8b9cb3712e5314bb44b4aeb129e69d.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=0 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/Modules/IssixModule/Items/issixsmap.png b/Modules/IssixModule/Items/issixsmap.png new file mode 100644 index 0000000..292acf7 Binary files /dev/null and b/Modules/IssixModule/Items/issixsmap.png differ diff --git a/Modules/IssixModule/Items/issixsmap.png.import b/Modules/IssixModule/Items/issixsmap.png.import new file mode 100644 index 0000000..1c82dc3 --- /dev/null +++ b/Modules/IssixModule/Items/issixsmap.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/issixsmap.png-69be316bd4e4ee3cbbea8dd1d419b13b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Modules/IssixModule/Items/issixsmap.png" +dest_files=[ "res://.import/issixsmap.png-69be316bd4e4ee3cbbea8dd1d419b13b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=0 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/Modules/IssixModule/Misc/asciimapsmall.txt b/Modules/IssixModule/Misc/asciimapsmall.txt new file mode 100644 index 0000000..6848c86 --- /dev/null +++ b/Modules/IssixModule/Misc/asciimapsmall.txt @@ -0,0 +1,19 @@ + ██????██ + ██????██ +██████████████████^^^^██████████████████████████████ +██████ ████████ ████████████████████MMMM██████ +██████ ████████ ████████████████████MMMM██████ +██ | ██ +██ | ██ +██████████ ████████████ | ████████EEEE██████ +██████████ ████████████ | ████████EEEE█████ +██ ████████████████████████████████████ +██ ███████████ +██████████ XXX ██ ██ +██████████ XXX ██ ██ ████ 69 +██████ ██ ██ ██████████ ██ +██████ ██ ██ ██ ██ ██ +██████████VVVV██ ██ ██ ██ + ██ ██████████ ██ + ██ ██ ████ + ██ diff --git a/Modules/IssixModule/Module.gd b/Modules/IssixModule/Module.gd new file mode 100644 index 0000000..1f5ddb9 --- /dev/null +++ b/Modules/IssixModule/Module.gd @@ -0,0 +1,249 @@ +extends Module +class_name IssixModule + +const APPROX_WALK_DELAY = 9 + +func getFlags(): + return { + "Issix_Introduced": flag(FlagType.Bool), + "Pets_Introduced": flag(FlagType.Bool), + "Score_Explored": flag(FlagType.Number), + "Quest_Status": flag(FlagType.Number), + "Quest_Rejected_By_Issix": flag(FlagType.Number), + "Azazel_Catnip_noticed": flag(FlagType.Bool), + "Azazel_Catnip_taken_today": flag(FlagType.Bool), + "Azazel_Affection_given": flag(FlagType.Number), + "Lamia_Times_Helped": flag(FlagType.Number), + "Hiisi_Affection": flag(FlagType.Number), + "Hiisi_Put_Sabotaged_Headvisors": flag(FlagType.Bool), + "Helped_Lamia_With_Drawings_Today": flag(FlagType.Bool), + "Quest_Bonked": flag(FlagType.Bool), + "Quest_Wait_Another_Day": flag(FlagType.Bool), + "Activated_Cabinets": flag(FlagType.Dict), + "Medical_Peeked": flag(FlagType.Bool), + "QuestionnaireQ1": flag(FlagType.Bool), # Creatures possess a soul + "QuestionnaireQ2": flag(FlagType.Bool), + "QuestionnaireQ3": flag(FlagType.Text), + "QuestionnaireQ4": flag(FlagType.Bool), + "QuestionnaireQ5": flag(FlagType.Text), + "QuestionnaireQ6": flag(FlagType.Bool), + "QuestionnaireQ7": flag(FlagType.Bool), + "QuestionnaireQ8": flag(FlagType.Text), + "QuestionnaireQ9": flag(FlagType.Bool), + "QuestionnaireQ10": flag(FlagType.Number), + "QuestionnaireQ11": flag(FlagType.Bool), + "Lamia_Is_Hungry": flag(FlagType.Bool), + "Azazel_Sky_Response": flag(FlagType.Bool), + "Received_Portrait_From_Lamia": flag(FlagType.Bool), + "Placed_Portrait_In_Cell": flag(FlagType.Bool), + "Hissi_RPS_data": flag(FlagType.Dict), + "Hiisi_Name_Helped": flag(FlagType.Bool), + "Shared_Marshmallows": flag(FlagType.Bool), + + # Slavery related + "PC_Enslavement_Role": flag(FlagType.Number), + "PC_Enslavement_Noncon": flag(FlagType.Bool), + "PC_Training_Level": flag(FlagType.Number), + "Issix_Mood": flag(FlagType.Number), + "Todays_Bred_Slave": flag(FlagType.Text), + "Progression_Day_Next": flag(FlagType.Number), + "Last_Day_Visited_Master": flag(FlagType.Number), + "Misc_Slavery_Info": flag(FlagType.Dict), + "Progression_Points": flag(FlagType.Number), + "Taught_To_Use_Bowl": flag(FlagType.Bool), + "Issix_Branded_PC": flag(FlagType.Bool), + "Pet_Time_Interaction_Today": flag(FlagType.Number), + "Is_Player_Forced_Today": flag(FlagType.Number), # If player is forced to stay in harem this will have amount of seconds player needs to spend in the harem today + "Last_Walk": flag(FlagType.Number), + "Eaten_Today": flag(FlagType.Bool), + "Comic_Books": flag(FlagType.Number), + "Comic_Book_Unlocked": flag(FlagType.Bool), + "Strikes_For_Disobedience": flag(FlagType.Number), + "Unwelcome_At_Corner": flag(FlagType.Bool), + "Had_Sex_With_Issix": flag(FlagType.Bool), + "Litter_Guessing_Game": flag(FlagType.Dict), + "Have_Received_Headpats_Lamia": flag(FlagType.Bool), + "Received_Headpats_From_Lamia": flag(FlagType.Number) + #"Gym_Bullies_Left_Alone": flag(FlagType.Bool) Currently cannot change the behavior of this :( + } + + +func _init(): + id = "IssixModule" + author = "Frisk" + + events = [ + "res://Modules/IssixModule/Events/EngRoomClosetEvent.gd", + "res://Modules/IssixModule/Events/EventTileOnEnter.gd", + "res://Modules/IssixModule/Events/GreenhouseCatnipEvent.gd", + "res://Modules/IssixModule/Events/IssixQuestionnaireEvent.gd", + "res://Modules/IssixModule/Events/MedicalPeekEvent.gd", + "res://Modules/IssixModule/Events/PetWalkExamEvent.gd", + "res://Modules/IssixModule/Events/PlayerCellModifierEvent.gd", + "res://Modules/IssixModule/Events/CornerPriorityEvent.gd", + "res://Modules/IssixModule/Events/SlaveryIntroEvent.gd", + "res://Modules/IssixModule/Events/IssixRegularSearch.gd" + #"res://Modules/IssixModule/Events/Overwrites/BullyGangEvent.gd" Cannot overwrite module that loads after + ] + + scenes = [ + "res://Modules/IssixModule/Scenes/EngRoomScene.gd", + "res://Modules/IssixModule/Scenes/GreenhouseCatnipStealScene.gd", + "res://Modules/IssixModule/Scenes/IssixQuestionnaireScene.gd", + "res://Modules/IssixModule/Scenes/IssixTalkMain.gd", + "res://Modules/IssixModule/Scenes/MedicalPeekScene.gd", + "res://Modules/IssixModule/Scenes/NoPetsTalkMain.gd", + "res://Modules/IssixModule/Scenes/PetsTalkMain.gd", + "res://Modules/IssixModule/Scenes/PetWalkExamScene.gd", + "res://Modules/IssixModule/Scenes/PlayerCellModifierScene.gd", + "res://Modules/IssixModule/Scenes/Overwrites/EatInCanteenScene.gd", + "res://Modules/IssixModule/Scenes/SlaveryFirst/SlaveryIntroContScene.gd", + "res://Modules/IssixModule/Scenes/SlaveryFirst/SlaveryTrainingBowlScene.gd", + "res://Modules/IssixModule/Scenes/SlaveryFirst/SlaveryBrandingScene.gd", + "res://Modules/IssixModule/Scenes/CaughtInTheCloset.gd", + "res://Modules/IssixModule/Scenes/SlaveryIntroScene.gd", + "res://Modules/IssixModule/Scenes/SlaveryInfoScreenScene.gd", + "res://Modules/IssixModule/Scenes/SlaveryFirst/IssixBringsComicbooks.gd", + #"res://Modules/IssixModule/Scenes/Overwrites/BullyGangScene.gd" + "res://Modules/IssixModule/Scenes/SlaveryFirst/IssixFindsAvoidingPlayer.gd" + ] + + characters = [ + "res://Modules/IssixModule/Characters/AzazelCharacter.gd", + "res://Modules/IssixModule/Characters/HiisiCharacter.gd", + "res://Modules/IssixModule/Characters/IssixCharacter.gd", + "res://Modules/IssixModule/Characters/LamiaCharacter.gd" + ] + + worldEdits = [ + "res://Modules/IssixModule/IssixWorldEdit.gd" + ] + + items = [ + "res://Modules/IssixModule/Items/CatnipItem.gd", + "res://Modules/IssixModule/Items/ClosetMap.gd", + "res://Modules/IssixModule/Items/CookieItem.gd" # I just felt like this game needs more variety in items, even if by themselves they don't do much + ] + + quests = [ + "res://Modules/IssixModule/IssixPetQuest.gd" + ] + + GlobalRegistry.registerLustTopicFolder("res://Modules/IssixModule/InterestTopics/") + GlobalRegistry.registerSkinsFolder("res://Modules/IssixModule/Skins/") + GlobalRegistry.registerStatusEffectFolder("res://Modules/IssixModule/StatusEffects/") + GlobalRegistry.sortRegisteredStatusEffectsByPriority() + GlobalRegistry.registerMapFloorFolder("res://Modules/IssixModule/Floors/") + GlobalRegistry.registerSpeechModifiersFolder("res://Modules/IssixModule/SpeechModifiers/") + GlobalRegistry.registerAttackFolder("res://Modules/IssixModule/Attacks/", true) + +# External +# "res://Scenes/ParadedOnALeashScene.gd" +# "res://Game/World/Floors/Closet.gd" +# "res://Game/World/Floors/Closet.tscn" + +static func addSceneToWatched(scene: String): + var scenes = GM.main.getModuleFlag("IssixModule", "Misc_Slavery_Info", {"scenes_seen": []}) + scenes["scenes_seen"].append(scene) + GM.main.setModuleFlag("IssixModule", "Misc_Slavery_Info", scenes.duplicate(true)) + +static func addIssixMood(mood: int): + GM.main.setModuleFlag("IssixModule", "Issix_Mood", clamp(GM.main.getModuleFlag("IssixModule", "Issix_Mood", 50)+mood, 0, 100)) + +static func getWalkDelay(): + return APPROX_WALK_DELAY + +static func getPlayerRole(): + return "pet" if GM.main.getModuleFlag("IssixModule", "PC_Enslavement_Role", 1) == 1 else "prostitute" + +static func playerToFuck(): + return not (int(GM.main.getDays()) % 2 != 0) and GM.main.getModuleFlag("IssixModule", "Todays_Bred_Slave", "") == "pc" + +static func getPlayerPetName(): + if Species.Canine in GM.pc.getSpecies(): + return "puppy" + elif Species.Feline in GM.pc.getSpecies(): + return "kitty" + elif Species.Equine in GM.pc.getSpecies(): + return "pony" + else: + return "pet" + +func breedSlaveIfNpc(): + ## Function to process breeding by Master on randomly selected TODO maybe do that during the day as an event? + if not (int(GM.main.getDays()) % 2 != 0): # Breed only every second day? + GM.main.setModuleFlag("IssixModule", "Todays_Bred_Slave", "thischardoesntexist") + return + var available_slaves = ['azazel', 'pc', 'hiisi'] + available_slaves.erase(GM.main.getModuleFlag("IssixModule", "Todays_Bred_Slave", "pc")) # Don't repeat same slave every day' + var current_slave = RNG.pick(available_slaves) + GM.main.setModuleFlag("IssixModule", "Todays_Bred_Slave", current_slave) + if current_slave == "pc": + return # This will be handled by separate event + current_slave = GM.main.getCharacter(current_slave) + GlobalRegistry.getCharacter("issix").prepareForSexAsDom() + if RNG.chance(5): + current_slave.cummedInMouthBy("issix") + if current_slave.hasVagina(): # azazel + current_slave.cummedInVaginaBy("issix", FluidSource.Penis, 1.8) + print("Azazel cummed in") + if RNG.chance(40): + current_slave.cummedInAnusBy("issix", FluidSource.Penis, 1.2) + else: # hiisi + print("Hiisi cummed in") + current_slave.cummedInAnusBy("issix") + +func calculateDailyScore() -> int: + ## For calculating player's daily activities at the end of the day + var score = 0 + if playerToFuck(): + if GM.main.getModuleFlag("IssixModule", "Had_Sex_With_Issix", false) == false: + score -= 5 + else: + score += 5 + if GM.main.getModuleFlag("IssixModule", "PC_Enslavement_Role", 0) == 1: + var time_forced = GM.main.getModuleFlag("IssixModule", "Is_Player_Forced_Today", 0) + var time_served = GM.main.getModuleFlag("IssixModule", "Pet_Time_Interaction_Today", 0) + if time_forced > 0: + if time_served >= time_forced: + score += 1 + else: + score -= 7 + else: + if time_served >= 60*60: + score += 1 + else: + score -= 5 + return score + +func tickDay(): + addIssixMood(RNG.randi_range(-7, 7)) + if GM.pc.getLocation() != "medical_paddedcell_player": + pass # TODO Bust out scene + elif (GM.main.getDays() - GM.main.getModuleFlag("IssixModule", "Last_Day_Visited_Master", GM.main.getDays()) > 1): + addIssixMood(-10) + addIssixMood(calculateDailyScore()) + if int(GM.main.getDays()) % 7 == 0: + GM.main.increaseModuleFlag("IssixModule", "Comic_Books", RNG.randi_range(5, 8)) + if int(GM.main.getDays()) % 30 == 0 and GM.main.getModuleFlag("IssixModule", "Strikes_For_Disobedience", 0) > 0: # every 30 days remove one strike + GM.main.increaseModuleFlag("IssixModule", "Strikes_For_Disobedience", -1) + if GM.main.getDays()-GM.main.getModuleFlag("IssixModule", "Last_Walk", GM.main.getDays()) == APPROX_WALK_DELAY: + GM.main.setModuleFlag("IssixModule", "Last_Walk", GM.main.getDays()) + + +func resetFlagsOnNewDay(): # I apologize for abusing this hook, but startNewDay does not have ANY other hooks I can use and SleepInCell as a trigger is not covering all cases of days passing by + if GM.main.getModuleFlag("IssixModule", "PC_Enslavement_Role", 0) > 0: # Slavery module + tickDay() + if GM.main.getModuleFlag("IssixModule", "Have_Received_Headpats_Lamia") != null: + GM.main.setModuleFlag("IssixModule", "Have_Received_Headpats_Lamia", false) + GM.main.setModuleFlag("IssixModule", "Azazel_Catnip_taken_today", false) + GM.main.setModuleFlag("IssixModule", "Activated_Cabinets", {}) + GM.main.setModuleFlag("IssixModule", "Quest_Wait_Another_Day", false) + GM.main.setModuleFlag("IssixModule", "Unwelcome_At_Corner", false) + GM.main.setModuleFlag("IssixModule", "Had_Sex_With_Issix", false) + GM.main.setModuleFlag("IssixModule", "Is_Player_Forced_Today", 0) + breedSlaveIfNpc() + if GM.main.getModuleFlag("IssixModule", "Helped_Lamia_With_Drawings_Today") != null: + GM.main.setModuleFlag("IssixModule", "Helped_Lamia_With_Drawings_Today", false) + GM.main.setModuleFlag("IssixModule", "Pet_Time_Interaction_Today", 0) + GM.main.setModuleFlag("IssixModule", "Eaten_Today", false) diff --git a/Modules/IssixModule/Reputation/Slave.gd b/Modules/IssixModule/Reputation/Slave.gd new file mode 100644 index 0000000..6cdd75c --- /dev/null +++ b/Modules/IssixModule/Reputation/Slave.gd @@ -0,0 +1,51 @@ +extends RepStatBase +# Currently just an idea +func _init(): + id = "PCSlave" + +func getVisibleName(): + return "Slave's Reputation" + +func getMaxLevel() -> int: + return 4 + +func getMinLevel() -> int: + return -1 + +func getTextForLevel(_level:int, _rep): + if(_level <= -1): + return "Regular" + if(_level == 0): + return "Unknown" + if(_level == 1): + return "Servant" + if(_level == 2): + return "Owned slut" + if(_level == 3): + return "Slave" + if(_level == 4): + return "Someone's property" + return "FUCK TOY" + +#func getSpecialRequirementToReachLevel(_level:int, _rep): +# if(_level == 3): +# return ["enslavesomeone", "Enslave anyone"] +# if(_level == 5): +# return ["makeobey", "Make any slave submit to you.. or break their mind"] +# +# return null + +func getEffectsInfoForLevel(_level:int, _rep) -> Array: + if(_level <= 3): + return ["More degradation from the inmates"] + if(_level <= 5): + return [ + "Less encounters with inmates, less cheating.", + ] + if(_level <= 8): + return [ + "" + ] + return [ + "Easier to make friends with staff.", + ] diff --git a/Scenes/CaughtInTheCloset.gd b/Modules/IssixModule/Scenes/CaughtInTheCloset.gd similarity index 100% rename from Scenes/CaughtInTheCloset.gd rename to Modules/IssixModule/Scenes/CaughtInTheCloset.gd diff --git a/Scenes/EngRoomScene.gd b/Modules/IssixModule/Scenes/EngRoomScene.gd similarity index 100% rename from Scenes/EngRoomScene.gd rename to Modules/IssixModule/Scenes/EngRoomScene.gd diff --git a/Scenes/GreenhouseCatnipStealScene.gd b/Modules/IssixModule/Scenes/GreenhouseCatnipStealScene.gd similarity index 100% rename from Scenes/GreenhouseCatnipStealScene.gd rename to Modules/IssixModule/Scenes/GreenhouseCatnipStealScene.gd diff --git a/Scenes/IssixQuestionnaireScene.gd b/Modules/IssixModule/Scenes/IssixQuestionnaireScene.gd similarity index 100% rename from Scenes/IssixQuestionnaireScene.gd rename to Modules/IssixModule/Scenes/IssixQuestionnaireScene.gd diff --git a/Scenes/IssixTalkMain.gd b/Modules/IssixModule/Scenes/IssixTalkMain.gd similarity index 100% rename from Scenes/IssixTalkMain.gd rename to Modules/IssixModule/Scenes/IssixTalkMain.gd diff --git a/Scenes/MedicalPeekScene.gd b/Modules/IssixModule/Scenes/MedicalPeekScene.gd similarity index 100% rename from Scenes/MedicalPeekScene.gd rename to Modules/IssixModule/Scenes/MedicalPeekScene.gd diff --git a/Scenes/NoPetsTalkMain.gd b/Modules/IssixModule/Scenes/NoPetsTalkMain.gd similarity index 100% rename from Scenes/NoPetsTalkMain.gd rename to Modules/IssixModule/Scenes/NoPetsTalkMain.gd diff --git a/Scenes/Overwrites/EatInCanteenScene.gd b/Modules/IssixModule/Scenes/Overwrites/EatInCanteenScene.gd similarity index 100% rename from Scenes/Overwrites/EatInCanteenScene.gd rename to Modules/IssixModule/Scenes/Overwrites/EatInCanteenScene.gd diff --git a/Scenes/PetWalkExamScene.gd b/Modules/IssixModule/Scenes/PetWalkExamScene.gd similarity index 100% rename from Scenes/PetWalkExamScene.gd rename to Modules/IssixModule/Scenes/PetWalkExamScene.gd diff --git a/Scenes/PetsTalkMain.gd b/Modules/IssixModule/Scenes/PetsTalkMain.gd similarity index 100% rename from Scenes/PetsTalkMain.gd rename to Modules/IssixModule/Scenes/PetsTalkMain.gd diff --git a/Scenes/PlayerCellModifierScene.gd b/Modules/IssixModule/Scenes/PlayerCellModifierScene.gd similarity index 100% rename from Scenes/PlayerCellModifierScene.gd rename to Modules/IssixModule/Scenes/PlayerCellModifierScene.gd diff --git a/Scenes/SlaveryFirst/IssixBringsComicbooks.gd b/Modules/IssixModule/Scenes/SlaveryFirst/IssixBringsComicbooks.gd similarity index 100% rename from Scenes/SlaveryFirst/IssixBringsComicbooks.gd rename to Modules/IssixModule/Scenes/SlaveryFirst/IssixBringsComicbooks.gd diff --git a/Scenes/SlaveryFirst/IssixFindsAvoidingPlayer.gd b/Modules/IssixModule/Scenes/SlaveryFirst/IssixFindsAvoidingPlayer.gd similarity index 100% rename from Scenes/SlaveryFirst/IssixFindsAvoidingPlayer.gd rename to Modules/IssixModule/Scenes/SlaveryFirst/IssixFindsAvoidingPlayer.gd diff --git a/Scenes/SlaveryFirst/SlaveryBrandingScene.gd b/Modules/IssixModule/Scenes/SlaveryFirst/SlaveryBrandingScene.gd similarity index 100% rename from Scenes/SlaveryFirst/SlaveryBrandingScene.gd rename to Modules/IssixModule/Scenes/SlaveryFirst/SlaveryBrandingScene.gd diff --git a/Scenes/SlaveryFirst/SlaveryIntroContScene.gd b/Modules/IssixModule/Scenes/SlaveryFirst/SlaveryIntroContScene.gd similarity index 100% rename from Scenes/SlaveryFirst/SlaveryIntroContScene.gd rename to Modules/IssixModule/Scenes/SlaveryFirst/SlaveryIntroContScene.gd diff --git a/Scenes/SlaveryFirst/SlaveryTrainingBowlScene.gd b/Modules/IssixModule/Scenes/SlaveryFirst/SlaveryTrainingBowlScene.gd similarity index 100% rename from Scenes/SlaveryFirst/SlaveryTrainingBowlScene.gd rename to Modules/IssixModule/Scenes/SlaveryFirst/SlaveryTrainingBowlScene.gd diff --git a/Scenes/SlaveryInfoScreenScene.gd b/Modules/IssixModule/Scenes/SlaveryInfoScreenScene.gd similarity index 100% rename from Scenes/SlaveryInfoScreenScene.gd rename to Modules/IssixModule/Scenes/SlaveryInfoScreenScene.gd diff --git a/Scenes/SlaveryIntroScene.gd b/Modules/IssixModule/Scenes/SlaveryIntroScene.gd similarity index 100% rename from Scenes/SlaveryIntroScene.gd rename to Modules/IssixModule/Scenes/SlaveryIntroScene.gd diff --git a/Modules/IssixModule/Skins/AzazelSkin/AzazelSkin.gd b/Modules/IssixModule/Skins/AzazelSkin/AzazelSkin.gd new file mode 100644 index 0000000..b882f29 --- /dev/null +++ b/Modules/IssixModule/Skins/AzazelSkin/AzazelSkin.gd @@ -0,0 +1,16 @@ +extends SkinBase + +func _init(): + id = "AzazelSkin" + +func getName(): + return "Azazel" + +func getPatternTexture(): + return preload("res://Modules/IssixModule/Skins/AzazelSkin/AzazelSkin.png") + +func getFittingSkinTypes(): + return { + SkinType.Fur: 1.0, + SkinType.Scales: 0.0, + } diff --git a/Modules/IssixModule/Skins/AzazelSkin/AzazelSkin.png b/Modules/IssixModule/Skins/AzazelSkin/AzazelSkin.png new file mode 100644 index 0000000..98563b2 Binary files /dev/null and b/Modules/IssixModule/Skins/AzazelSkin/AzazelSkin.png differ diff --git a/Modules/IssixModule/Skins/AzazelSkin/AzazelSkin.png.import b/Modules/IssixModule/Skins/AzazelSkin/AzazelSkin.png.import new file mode 100644 index 0000000..b4abe42 --- /dev/null +++ b/Modules/IssixModule/Skins/AzazelSkin/AzazelSkin.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/AzazelSkin.png-4d000ffaba6bb3818dfcb0d471df4950.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Modules/IssixModule/Skins/AzazelSkin/AzazelSkin.png" +dest_files=[ "res://.import/AzazelSkin.png-4d000ffaba6bb3818dfcb0d471df4950.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=0 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/Modules/IssixModule/SpeechModifiers/LamiaMute.gd b/Modules/IssixModule/SpeechModifiers/LamiaMute.gd new file mode 100644 index 0000000..5bb7dad --- /dev/null +++ b/Modules/IssixModule/SpeechModifiers/LamiaMute.gd @@ -0,0 +1,11 @@ +extends SpeechModifierBase + +func _init(): # Assure that Lamia never is assigned any kind of dialogue by the game + id = "LamiaMute" + priority = 1001 + +func appliesTo(_speaker: BaseCharacter) -> bool: + return _speaker.getID() == "lamia" + +func modify(_text: String, _speaker: BaseCharacter) -> String: + return "..." diff --git a/Modules/IssixModule/StatusEffects/BrandingPain.gd b/Modules/IssixModule/StatusEffects/BrandingPain.gd new file mode 100644 index 0000000..321e328 --- /dev/null +++ b/Modules/IssixModule/StatusEffects/BrandingPain.gd @@ -0,0 +1,48 @@ +extends StatusEffectBase + +func _init(): + id = "AfterBrandPain" + isBattleOnly = false + +func initArgs(_args = []): + if(_args.size() > 0): + turns = _args[0] + else: + turns = 48*60*60 + +func processBattleTurn(): + pass + +func processTime(_secondsPassed: int): + turns -= _secondsPassed + if(turns <= 0): + stop() + +func getEffectName(): + return "Branding pain" + +func getEffectDesc(): + return "Your skin burns like fire and you can't wear any clothes for "+Util.getTimeStringHumanReadable(turns) + +func getEffectImage(): + return "res://Modules/IssixModule/StatusEffects/brandpain.png" + +func getIconColor(): + return IconColorRed + +func combine(_args = []): + if(_args.size() > 0): + turns = max(_args[0], turns) + +func getBuffs(): + return [ + buff(Buff.AmbientPainBuff, [40.0]), + ] + +func saveData(): + return { + "turns": turns, + } + +func loadData(_data): + turns = SAVE.loadVar(_data, "turns", 60*60) diff --git a/Scenes/ParadedOnALeashScene.gd b/Scenes/ParadedOnALeashScene.gd new file mode 100644 index 0000000..ccf14f5 --- /dev/null +++ b/Scenes/ParadedOnALeashScene.gd @@ -0,0 +1,120 @@ +extends "res://Scenes/SceneBase.gd" + +var startLocation = "" +var endLocation = "" +var path = [] +var whoLeashingID = "" +var randomChat = [] +var teleportwhenskipped = true +var pose = "walk" + +func _initScene(_args = []): + whoLeashingID = _args[0] + startLocation = _args[1] + endLocation = _args[2] + if(_args.size() > 3): + randomChat = _args[3] + if (_args.size() > 4): + teleportwhenskipped = _args[4] + if (_args.size() > 5): + pose = _args[5] + + path = GM.world.calculatePath(startLocation, endLocation) + if(path.size() <= 0): + endScene() + +func _init(): + sceneID = "ParadedOnALeashScene" + +func _run(): + if(state == ""): + addCharacter(whoLeashingID) + + if(state == "" || state == "leashed"): + if state == "leashed": + playAnimation(StageScene.Duo, pose, {npc=whoLeashingID, npcAction="walk", flipNPC=true, bodyState={leashedBy=whoLeashingID}}) + if(path.size() > 0): + aimCameraAndSetLocName(path[0]) + + var _roomInfo = GM.world.getRoomByID(path[0]) + + if(_roomInfo == null): + saynn("You're being walked on a leash by {leasher.name}") + else: + saynn("You're being walked on a leash by {leasher.name}") + + if(GM.pc.isBlindfolded() && !GM.pc.canHandleBlindness()): + saynn(_roomInfo.getBlindDescription()) + else: + saynn(_roomInfo.getDescription()) + + if(randomChat.size() > 0 && RNG.chance(min(30, randomChat.size() * 10))): + saynn("[say=leasher]"+RNG.pick(randomChat)+"[/say]") + + if (teleportwhenskipped): + addButton("Skip", "Skip the walk", "skipwalk") + else: + addButton("Skip", "Skip the walk", "endthescene") + addButtonAt(6, "Follow", "Follow the leash", "follow") + addDisabledButtonAt(10, "Leashed", "Can't escape from the leash") + addDisabledButtonAt(11, "Leashed", "Can't escape from the leash") + addDisabledButtonAt(12, "Leashed", "Can't escape from the leash") + if (state == "skipwalk"): + aimCamera(endLocation) + GM.pc.setLocation(endLocation) + + endScene() + +func _react(_action: String, _args): + if(_action == "endthescene"): + endScene() + return + + if(_action == "follow"): + if(path.size() == 0): + endScene() + return + + var nextLoc = path[0] + path.remove(0) + + if(!GM.world.hasRoomID(nextLoc)): + endScene() + return + + GM.pc.setLocation(nextLoc) + if(path.size() == 0): + endScene() + return + setState("leashed") + return + + setState(_action) + +func saveData(): + var data = .saveData() + + data["startLocation"] = startLocation + data["endLocation"] = endLocation + data["path"] = path + data["whoLeashingID"] = whoLeashingID + data["randomChat"] = randomChat + data["teleportwhenskipped"] = teleportwhenskipped + + return data + +func loadData(data): + .loadData(data) + + startLocation = SAVE.loadVar(data, "startLocation", "") + endLocation = SAVE.loadVar(data, "endLocation", "") + path = SAVE.loadVar(data, "path", []) + whoLeashingID = SAVE.loadVar(data, "whoLeashingID", "") + randomChat = SAVE.loadVar(data, "randomChat", []) + teleportwhenskipped = SAVE.loadVar(data, "teleportwhenskipped", true) + +func resolveCustomCharacterName(_charID): + if(_charID == "leasher" && whoLeashingID != ""): + return whoLeashingID + + return null