avatars.js 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579
  1. var AVATAR_TRAITS = ["submissiveness", "domesticity", "maternalism", "allure", "orientation"];
  2. function switchFemForMascTrait(trait) {
  3. switch(trait) {
  4. case "submissiveness": return "Dominance";
  5. case "domesticity": return "Adventurousness";
  6. case "maternalism": return "Paternity";
  7. case "allure": return "Lustfulness";
  8. case "orientation": return "Attraction to ♀";
  9. }
  10. }
  11. function Avatar(submissiveness, domesticity, maternalism, allure, orientation) {
  12. // Variables
  13. var that = this;
  14. // Identity
  15. this.name = ""; // special case for "Rival man" in battle and drawfigure.js
  16. this.round = 0; // day of game for player, day of capture for a woman, day met for a NPC
  17. this.daysLeader =0; //Number of cumulative days they have spent as clan leader.
  18. // Futanari
  19. this.futa = 0; // > 0 if a futa
  20. // Power
  21. this.changra = getRandomInt(75, 100);
  22. // Traits
  23. this.submissiveness = submissiveness;
  24. this.domesticity = domesticity;
  25. this.maternalism = maternalism;
  26. this.allure = allure;
  27. this.orientation = orientation;
  28. // Motherhood
  29. this.pregnancy = 0;
  30. this.childrenboy = 0;
  31. this.childrengirl = 0;
  32. this.pregnancyMessage = 0;
  33. this.impregnator=false;//Will be set to father of baby
  34. //fatherhood
  35. this.fatheredboy=0;
  36. this.fatheredgirl=0;
  37. // Desire
  38. this.desire = 0;
  39. this.description = { };
  40. this.activity = "";
  41. this.natural = { };
  42. this.minimums = { };
  43. this.maximums = { };
  44. //Permissions
  45. this.allowForage = false;
  46. // Trainings (via experience or some items)
  47. this.experience = 0;
  48. this.Mods = {
  49. "ironwill": 0,
  50. "breasts": 0,
  51. "changra": 0,
  52. "perception": 0,
  53. "amazon": 0,
  54. "cock": 0,
  55. "futa": 0,
  56. "balls": 0,
  57. // Bonuses to Push
  58. "pushsubmissiveness": 0,
  59. "pushdomesticity": 0,
  60. "pushmaternalism": 0,
  61. "pushallure": 0,
  62. "pushorientation": 0,
  63. // Resistances
  64. "resistsubmissiveness": 0,
  65. "resistdomesticity": 0,
  66. "resistmaternalism": 0,
  67. "resistallure": 0,
  68. "resistorientation": 0,
  69. // Crafting
  70. "infuse": 0,
  71. "craftnipplerings": 0,
  72. "craftclitcockring": 0,
  73. "craftcollar": 0,
  74. "craftheadband": 0,
  75. "craftbellybuttonstud": 0,
  76. "craftleftbracelet": 0
  77. };
  78. this.getTrainingRanks = function(nc)
  79. {
  80. this.capTraits(); // ensure they are all initialised
  81. var val = this.Mods.ironwill + (this.Mods.perception / 5) + (this.Mods.changra / 5);
  82. if (nc === true) {
  83. // rank that do not affect combat
  84. val += (this.Mods.breasts / 10) + (this.Mods.amazon / 2) + (this.Mods.cock / 2) + (this.Mods.futa / 2);
  85. val += this.physique.breastrows + this.physique.horns + this.physique.tail + this.physique.wings;
  86. }
  87. val += (this.Mods.pushsubmissiveness / 2) + (this.Mods.pushdomesticity / 2) + (this.Mods.pushmaternalism / 2) + (this.Mods.pushallure / 2) + (this.Mods.pushorientation / 2);
  88. val += this.Mods.resistsubmissiveness + this.Mods.resistdomesticity + this.Mods.resistmaternalism + this.Mods.resistallure + this.Mods.resistorientation;
  89. return Math.ceil(val);
  90. };
  91. // Physique
  92. this.physique = {
  93. "hairc": getRandomInt(1, 20),
  94. "hairstyle": getRandomInt(0, 9),
  95. // special numbers 100 = red, 101 = blue
  96. "irisc": getRandomInt(1, 20),
  97. "skin": getRandomInt(1, 20),
  98. // Body parts
  99. "breastrows": 0,
  100. "hornstype": 0,
  101. "horns": 0,
  102. "tailtype": 0,
  103. "tail": 0,
  104. "wings": 0,
  105. "gentialscnt": 1,
  106. "twins" : 5
  107. };
  108. // Possessions
  109. // Your women
  110. this.women = [];
  111. // Goods
  112. this.goods = 0;
  113. this.metal = 0;
  114. // Items
  115. this.items = {
  116. "nipplerings": 0,
  117. "collar": 0,
  118. "headband": 0,
  119. "bellybuttonstud": 0,
  120. "clitcockring": 0,
  121. "leftbracelet": 0
  122. };
  123. this.isYourWoman = function(ps) {
  124. var index = 0;
  125. for (index = 0; index < women.length; index++) {
  126. if (women[index].name == ps) {
  127. // got them
  128. return player.women[index];
  129. }
  130. }
  131. return undefined;
  132. };
  133. // Switches, to use to events etc
  134. // value
  135. // 0 = Boss 1 fight assigned (true)
  136. // 1 = Osiris
  137. // 32 true/false flags, 0-31
  138. this.switches1 = 0;
  139. // Methods
  140. this.checkSwitch = function(nOffSet) {
  141. return ((this.switches1 & (1 << nOffSet)) !== 0) ? true : false;
  142. };
  143. this.setSwitch = function(nOffSet, nVal) {
  144. if (nVal === undefined || nVal === true) this.switches1 = this.switches1 | (1 << nOffSet);
  145. else this.switches1 = this.switches1 & (~(1 << nOffSet));
  146. };
  147. this.femininity = function() {
  148. var total = 0;
  149. var that = this;
  150. $.each(AVATAR_TRAITS, function(index, trait) {
  151. total += that[trait];
  152. });
  153. return total / AVATAR_TRAITS.length;
  154. };
  155. this.isFemale = function () { return this.femininity() > 49; };
  156. this.isMale = function () { return !(this.isFemale() || this.isFutanari()); };
  157. this.hasVagina = function () {
  158. var tst = this.calcTestes(false);
  159. return tst > 11 || this.futa > 0;
  160. };
  161. this.masculinity = function () { return 100 - this.femininity(); };
  162. this.hasCock = function () {
  163. var tst = this.calcTestes(false);
  164. return tst <= 11 || this.futa > 0 || this.Mods.cock > 0;
  165. };
  166. this.isFutanari = function () { return this.hasCock() && this.hasVagina(); };
  167. this.checkCockNonFuta = function()
  168. {
  169. // check cock
  170. var hasc = this.hasCock();
  171. if (this.Mods.cock === 0 && this.futa > 0) {
  172. player.futa = 0;
  173. // Femininise Stats
  174. $.each(AVATAR_TRAITS, function(index, trait){
  175. that[trait] = that[trait] + 50;
  176. });
  177. hasc = this.hasCock();
  178. // Femininise Stats
  179. $.each(AVATAR_TRAITS, function(index, trait){
  180. that[trait] = that[trait] - 50;
  181. });
  182. this.futa = 1;
  183. }
  184. return hasc;
  185. };
  186. this.unFuta = function()
  187. {
  188. if (this.futa > 0) {
  189. // No longer a futa!!!!!
  190. // Irreversible, as such, can grow a cock but not this.futa
  191. // Femininise Stats
  192. $.each(AVATAR_TRAITS, function(index, trait){
  193. that[trait] = that[trait] + 50;
  194. that.changeNatural(trait, 50);
  195. });
  196. this.futa = 0;
  197. }
  198. };
  199. //vim conversion regex: (for converting from function to properties)
  200. //.,$s/this.\(\a*\) *= *\(function[^;]*\)/Object.defineProperty(this,"\1",{get:\2})/c
  201. //remove function calls from templates (ALL templates. be careful)
  202. // %s/${\( *\a* *. *\a* *\| *\a* *\)() *}/${\1}/g
  203. //alternatively, here is one that finds and replaces every use of the function
  204. //(get all function names) grep -oP "Object.defineProperty\(this,\"\K[a-zA-Z]*" ./avatars.js |sort | uniq | tr '\n' '\\|'
  205. //fuckhole\|genitals\|heshe\|HeShe\|himher\|HimHer\|hisher\|HisHer\|hishers\|HisHers\|isare\|manwoman\|youheshe\|YouHeShe\|youhimher\|YouHimHer\|youName\|YouName\|yourhisher\|YourHisHer\|yourNames\|YourNames\|yourshishers\|YoursHisHers\|yoursNames\|YoursNames\|youthey\|YouThey
  206. // %s/\(fuckhole\|genitals\|heshe\|HeShe\|himher\|HimHer\|hisher\|HisHer\|hishers\|HisHers\|isare\|manwoman\|youheshe\|YouHeShe\|youhimher\|YouHimHer\|youName\|YouName\|yourhisher\|YourHisHer\|yourNames\|YourNames\|yourshishers\|YoursHisHers\|yoursNames\|YoursNames\|youthey\|YouThey\)()/\1/g
  207. Object.defineProperty(this,"arousedReaction",{get:function(){//will want to add more later probably. Just getting basics for now
  208. var options = ["body feel horny"];//best to have something generic always
  209. if(this.calcBreasts()>2){
  210. options.push("breasts tingle");
  211. }
  212. if(this.hasVagina()){
  213. options=options.concat(["pussy ache"]);
  214. }
  215. if(this.hasCock()){
  216. options=options.concat(["cock swell"]);
  217. }
  218. return getRandomElem(options);
  219. }});
  220. Object.defineProperty(this,"sex",{get:function(){
  221. if(this.isMale()){
  222. return "male";
  223. }else if(this.isFutanari()){
  224. return "futa";
  225. }else if(this.isFemale()){
  226. return "female";
  227. }else{
  228. return "neuter";//don't think this is even possible.
  229. }
  230. });
  231. Object.defineProperty(this,"youName",{get:function(){return (player===this)?"you":this.name;}});
  232. Object.defineProperty(this,"YouName",{get:function(){return (player===this)?"You":capitalize(this.name);}});
  233. Object.defineProperty(this,"isare",{get:function(){return this===player?"are":"is";}});
  234. Object.defineProperty(this,"manwoman",{get:function(){return this.isMale()?"man":"woman";}});
  235. Object.defineProperty(this,"fuckhole",{get:function(){return this.hasVagina()?"pussy":"ass";}});
  236. Object.defineProperty(this,"genitals",{get:function(){return this.hasCock()?"cock":"pussy";}});
  237. Object.defineProperty(this,"yourNames",{get:function(){return this===player?"your":this.name+"'s";}});
  238. Object.defineProperty(this,"YourNames",{get:function(){return this===player?"Your":this.name+"'s";}});
  239. Object.defineProperty(this,"yoursNames",{get:function(){return this===player?"yours":this.name+"'s";}});
  240. Object.defineProperty(this,"YoursNames",{get:function(){return this===player?"Yours":this.name+"'s";}});
  241. /*Getting rid of unless we can find a way to make it a property. Normal functions don't work with handlebars*/
  242. /*Object.defineProperty(this,"YouThey",{get:function(other){return (this===player)||(other===player)?"You":"They";}});
  243. Object.defineProperty(this,"youthey",
  244. ` {get:function(other){return (this===player)||(other===player)?"you":"they";}});*/
  245. Object.defineProperty(this,"hashave",{get:function(){ return this===player?"have":"has";}});
  246. Object.defineProperty(this,"heshe",{get:function() { return this.femininity() > 49 || this.futa > 0 ? "she" : "he"; ;}});
  247. Object.defineProperty(this,"HeShe",{get:function() { return this.femininity() > 49 || this.futa > 0 ? "She" : "He"; ;}});
  248. Object.defineProperty(this,"youheshe",{get:function(){return this===player?"you":this.heshe;}})
  249. Object.defineProperty(this,"YouHeShe",{get:function(){return this===player?"You":this.HeShe;}})
  250. Object.defineProperty(this,"himher",{get:function() { return this.femininity() > 49 || this.futa > 0 ? "her" : "him"; }});
  251. Object.defineProperty(this,"HimHer",{get:function() { return this.femininity() > 49 || this.futa > 0 ? "Her" : "Him"; }});
  252. Object.defineProperty(this,"youhimher",{get:function(){return this===player?"you":this.himher;}})
  253. Object.defineProperty(this,"YouHimHer",{get:function(){return this===player?"You":this.HimHer;}})
  254. Object.defineProperty(this,"hisher",{get:function() { return this.femininity() > 49 || this.futa > 0 ? "her" : "his"; }});
  255. Object.defineProperty(this,"HisHer",{get:function() { return this.femininity() > 49 || this.futa > 0 ? "Her" : "His"; }});
  256. Object.defineProperty(this,"YourHisHer",{get:function(){return this===player?"Your":this.HisHer;}})
  257. Object.defineProperty(this,"yourhisher",{get:function(){return this===player?"your":this.hisher;}})
  258. Object.defineProperty(this,"hishers",{get:function() { return this.femininity() > 49 || this.futa > 0 ? "hers" : "his"; }});
  259. Object.defineProperty(this,"HisHers",{get:function() { return this.femininity() > 49 || this.futa > 0 ? "Hers" : "His"; }});
  260. Object.defineProperty(this,"yourshishers",{get:function(){return this===player?"yours":this.hishers;}})
  261. Object.defineProperty(this,"YoursHisHers",{get:function(){return this===player?"Yours":this.HisHers;}})
  262. this.cunning = function() { return this.Mods.perception + ((this.femininity() + this.allure) / 2); };
  263. this.perception = function() { return this.Mods.perception + Math.ceil((this.femininity() + 100 - this.domesticity)/2); };
  264. this.changeNatural = function(trait, val)
  265. {
  266. this.maximums[trait] += val;
  267. this.minimums[trait] += val;
  268. this.natural[trait] += val;
  269. };
  270. this.rest = function() {
  271. this.changra = 500;
  272. $.each(AVATAR_TRAITS, function(index, trait) {
  273. that[trait] = that.natural[trait];
  274. });
  275. this.capTraits();
  276. };
  277. this.isPregnant = function() {
  278. return this.pregnancy > 0;
  279. };
  280. this.maybeImpregnate = function(man){
  281. if(this.isPregnant()){return;}
  282. var prob = this.maternalism +20 - getRandomInt(50,100);
  283. if (prob>0){this.pregnancy=2.5;this.impregnator=man;}
  284. }
  285. this.advancePregnancy = function ()
  286. {
  287. if(this===player){
  288. if(player.isFemale() && player.maternalism>50 && (player.childrenboy>0||player.childrengirl>0)){
  289. if(getRandomInt(0,200)< (player.femininity()-player.masculinity()+player.maternalism-50+5*player.childrengirl+5*player.childrenboy)){
  290. this.activity+="You clutch baby to chest, sighing as it suckle milk from swolen breast. Is good being mother.";
  291. player.dysphoria-=5;
  292. }
  293. }
  294. }
  295. if (!this.isPregnant()) return;
  296. this.pregnancy += 2.5;
  297. if (this.pregnancy >= 15 && this.pregnancy <= 25 && this.pregnancyMessage === 0) {
  298. this.pregnancyMessage += 1;
  299. //Player
  300. if (this == player) {
  301. this.activity += "You feel strange in belly. You put hand on it. Belly feels soft and warm with Changra... you are with child!";
  302. if (player.isFemale()) {
  303. if (player.isFutanari()) {
  304. this.activity += this.activity + " You smile and pat belly. You make clan greater breeding woman and getting bred!";
  305. } else {
  306. this.activity += this.activity + " You smile and pat belly. You make clan greater with breeding more children!";
  307. }
  308. }
  309. if (!player.isFemale()) {
  310. this.activity += this.activity + " You frown. You should seed woman! Not get seed like woman!";
  311. }
  312. }
  313. //NPC
  314. else
  315. {
  316. var activity = this.name + " come to you, " + this.himher + " hand on stomach. " + this.HeShe + " telling you that she is with child.";
  317. if((player===leader)||(this.impregnator===player)){
  318. activity+="You proudly rub " + this.himher + " belly.";
  319. }else{
  320. if(player.dysphoria+getRandomInt(-25,25)>50){
  321. activity+=` You angry that ${this.heshe} have baby with other man.`;
  322. }else{
  323. activity+=` You coo excitedly and rub ${this.hisher} belly, congratulating her on carrying ${this.impregnator.name}\'s child.`;
  324. }
  325. }
  326. this.activity+=activity;
  327. player.doneTo+=activity;
  328. }
  329. }
  330. if (this.pregnancy >= 48 && this.pregnancy <= 55 && this.pregnancyMessage == 1) {
  331. this.pregnancyMessage += 1;
  332. //Player
  333. if (this == player) {
  334. this.activity = "Your belly is big from child, but still growing!";
  335. if (player.isFemale()) {
  336. if (player.isFutanari()) {
  337. this.activity += this.activity + " Your cock grow hard thinking about having more children.";
  338. } else {
  339. this.activity += this.activity + " You can't wait to have more children.";
  340. }
  341. }
  342. if (!player.isFemale()) {
  343. this.activity += this.activity + " You swear to gods to be more careful and not get bred again.";
  344. }
  345. }
  346. //NPC
  347. else {
  348. var activity = "<p>You see " + this.name + " with big belly."
  349. if((player===leader)||(this.impregnator===player)){
  350. activity+=" You smile.";
  351. }else{
  352. if(player.dysphoria+getRandomInt(-25,25)>50){
  353. activity+=" Seeing other man baby grow in her stokes huge rage.";
  354. player.dysphoria+=3;
  355. }else if((player.maternalism>75)&&(!player.isPregnant())){
  356. activity+=` You jealous of ${this.himher}.`;
  357. }else{
  358. activity+=` You happy for ${this.himher}.`;
  359. }
  360. }
  361. activity+="</p>";
  362. this.activity+=activity;
  363. player.doneTo+=activity;
  364. }
  365. }
  366. if (this.pregnancy >= 80 && this.pregnancyMessage == 2) {
  367. this.pregnancyMessage += 1;
  368. //Player
  369. if (this == player) {
  370. this.activity += "Your belly is huge from child, you can feel it moving inside you!";
  371. if (player.isFemale()) {
  372. if (player.isFutanari()) {
  373. this.activity += this.activity + " Soon your clan will grow! You feel getting hard, thinking about getting bred again.";
  374. } else {
  375. this.activity += this.activity + " Soon your clan will grow! You feel getting wet, thinking about having another child right after this.";
  376. }
  377. }
  378. if (!player.isFemale()) {
  379. this.activity += this.activity + " You hate belly. It huge hinderance.";
  380. }
  381. }
  382. //NPC
  383. else {
  384. this.activity += this.HeShe + " is waddling, " + this.hisher + " belly huge. Soon clan will have more children.";
  385. if (player.hasCock()&&(leader===player)) { this.activity = this.activity + " Your cock hard, wanting to " + this.himher + " again."; }
  386. }
  387. }
  388. if (this.pregnancy >= getRandomInt(90, 105)) {
  389. //this.activity = this == player ? "You" : this.HeShe;
  390. var num = getRandomInt(1, 100) < this.physique.twins ? 2 : 1;
  391. var bBoy = (this.items.leftbracelet > 0) ? ((this.items.leftbracelet == 2) ? false : (Math.random() < 0.5)) : true;
  392. var csex = bBoy?"boy":"girl";
  393. var crel = bBoy?"son":"daughter";
  394. var cheshe = num>1?"They":(bBoy?"He":"She");
  395. var cplur = num>1?"s":"";
  396. var activity;
  397. var reactMsg;
  398. if(player==leader){
  399. reactMsg = "Your clan grow.";
  400. }else{
  401. if(this!==player){
  402. if(this.impregnator==player){
  403. reactMsg=`${cheshe} yours, you just wish you were father again for ${crel}.`;
  404. player.dysphoria+=10;
  405. }else{
  406. if(player.dysphoria+getRandomInt(-20,20)>45){
  407. reactMsg = `${cheshe} not fathered by you, though. ${this.name} supposed to be your woman, it make you mad to see ${this.himher} having other man\'s child.`;
  408. player.dysphoria+=3;
  409. }else{
  410. if(player.pregnancy>15){
  411. reactMsg = `You rub own growing belly and think about increasing clan.`;
  412. }else{
  413. reactMsg = `Your own belly flat and empty. You wonder if ${leader.name} will give you baby soon.`;
  414. }
  415. }
  416. }
  417. }else{
  418. if(player.dysphoria+getRandomInt(-20,20)>45){
  419. if(player.maternalism>70){//If player has high maternalism, having a baby makes them accept womanhood more
  420. reactMsg="You smile and lift baby to breast. You still not want be woman, but maybe it not so bad if it means you can be mother too.";
  421. player.dysphoria-=5;
  422. }else{
  423. reactMsg="This wrong. You supposed to be fathering babies, not giving birth to them.";
  424. }
  425. }else{
  426. reactMsg=`It still strange and painful to give birth, but you happy bearing ${crel}${cplur} for ${leader.name}.`
  427. }
  428. }
  429. }
  430. if (num > 1){
  431. activity= `<p>${this.YouName} give birth to twins last night, fine ${crel}s. ${reactMsg}</p>`;
  432. }else {
  433. activity=`<p>${this.YouName} give birth to fine ${crel} last night. ${reactMsg}</p>`;
  434. }
  435. this.pregnancy = 0;
  436. this.pregnancyMessage = 0;
  437. this["children"+csex]+=num;
  438. if(this.impregnator){
  439. this.impregnator["fathered"+csex]+=num;
  440. }
  441. this.impregnator=false;
  442. console.log(activity);
  443. this.activity+=activity;
  444. player.doneTo+=activity;
  445. }
  446. };
  447. this.advanceDesire = function() {
  448. function calcDesire(subject, object) {
  449. var objectGender = object.masculinity() - 50;
  450. var desire = 0;
  451. if (subject.orientation < 50) {
  452. desire = (objectGender < 0) ? (objectGender * -2) : (objectGender * 2) * ((50 - subject.orientation) / 50);
  453. } else {
  454. desire = objectGender > 0 ? objectGender * 2 : (objectGender * -2) * ((subject.orientation - 50) / 50);
  455. }
  456. return (desire * ((110 - subject.submissiveness) / 100)) / 2;
  457. }
  458. var herDesire = calcDesire(this, player);
  459. if (this.items.nipplerings > 0 || this.items.clitcockring > 0) herDesire += 1;
  460. var playerDesire = calcDesire(player, this);
  461. this.desire += herDesire + playerDesire;
  462. };
  463. this.fornicate = function() {
  464. this.desire = 0;
  465. if(this.dysphoria>0){this.dysphoria-=getRandomInt(1,3+Math.round(this.desire/10));}
  466. //NPC only Vagina
  467. if (!this.hasCock() && this.hasVagina()) {
  468. if (leader.hasCock()) {
  469. this.PCfucksNPCvaginal(this);
  470. } else {
  471. this.activity += `${this.HeShe} come to ${leader.youName} and beg for release. ${leader.YouName} make ${this.himher} scream with tongue and finger. Then she lick ${this.youName} like shecat till ${this.youName} scream like beast.`;
  472. }
  473. }
  474. //NPC only Cock
  475. if (this.hasCock() && !this.hasVagina()) {
  476. if (leader.hasVagina() && !leader.hasCock()) {
  477. this.NPCfucksPCvaginal(this);
  478. }
  479. if (leader.hasCock()) {
  480. if (!leader.hasVagina()) {
  481. this.PCwithDickNPCwithDick(this);
  482. } else {
  483. var probPCfuck2 = getRandomInt(1, 100);
  484. if (!leader.isPregnant()) probPCfuck2 += 10;
  485. if (probPCfuck2 > 60) {
  486. this.NPCfucksPCvaginal(this);
  487. } else {
  488. this.PCwithDickNPCwithDick(this);
  489. }
  490. }
  491. }
  492. }
  493. //NPC is futa
  494. if (this.hasCock() && this.hasVagina()) {
  495. var probPCfuck3 = getRandomInt(1, 100);
  496. //player is male
  497. if (leader.hasCock() && !leader.hasVagina()) {
  498. if (probPCfuck3 < 80) { this.PCfucksNPCvaginal(this); }
  499. else { this.PCwithDickNPCwithDick(this); }
  500. }
  501. //player is female
  502. if (!leader.hasCock() && leader.hasVagina()) {
  503. this.NPCfucksPCvaginal(this);
  504. }
  505. //player is futa
  506. if (leader.hasCock() && leader.hasVagina()) {
  507. if (!leader.isPregnant()) probPCfuck3 += 10;
  508. if (probPCfuck3 < 70) {
  509. this.PCfucksNPCvaginal(this);
  510. } else {
  511. this.NPCfucksPCvaginal(this);
  512. }
  513. }
  514. }
  515. };
  516. this.PCwithDickNPCwithDick = function (avatar)
  517. {
  518. var probPCgetFucked = getRandomInt(1, 100);
  519. if (leader.hasVagina()) { probPCgetFucked -= 10; }
  520. if (probPCgetFucked > 70) {
  521. avatar.activity += ` ${avatar.HeShe} come to ${leader.youName} at night. ${leader.YouName} look at cock and turn around, moving ass like woman. ${avatar.HeShe} takes invitation and fucks ${leader.youName} in manhole. ${leader.YouName} moan like woman and release seed on ground.`;
  522. //avatar.dysphoria+=4;
  523. } else {
  524. avatar.activity += `${avatar.HeShe} come to ${leader.youName} at night and in need. ${leader.youName} push ${avatar.himher} on stomach and fuck manhole like pussy, releasing ${leader.yourhisher} seed in it.`;
  525. }
  526. };
  527. this.NPCfucksPCvaginal = function (avatar) {
  528. var probPCgetFucked = getRandomInt(1, 100);
  529. if (!player.isPregnant()) { probPCgetFucked += 20; }
  530. var prob2;
  531. if (player.submissiveness-avatar.submissiveness>20){
  532. avatar.activity += `${avatar.HeShe} throw ${leader.youName} to dirt and mount ${leader.yourhisher} pussy. ${avatar.HeShe} fuck ${leader.youName} hard, making ${leader.youName} cry like shebeast in heat until ${leader.youName} cum. Soon his seed erupt inside ${leader.youhimher}`;
  533. //avatar.dysphoria+=5;
  534. eatStatNut(leader,"submissiveness",2);
  535. eatStatNut(rival,"submissiveness",-10);
  536. }
  537. else if (probPCgetFucked < 70) {
  538. avatar.activity += `${leader.YouName} feel desire. ${leader.YouHeShe} push ${player===leader?avatar.himher:avatar.name} down and ride cock. ${avatar.YouHeShe} scream like shebeast as ${leader.youheshe} come.`;
  539. if (player.hasCock()) { avatar.activity += avatar.activity + ` ${leader.YouName} coat ${avatar.hisher} stomach with ${leader.yourhisher} seed.`; }
  540. if (!player.isPregnant()) {
  541. prob2 = (player.maternalism + 20) - getRandomInt(50, 100);
  542. if (prob2 > 0) {
  543. player.pregnancy = 2.5;
  544. player.impregnator=leader;
  545. avatar.activity += `${leader.youName} feel desire. ${leader.YouHeShe} push ${avatar.himher} down and ride cock. ${leader.YouHeShe} scream like shebeast as ${leader.youheshe} feel${avatar.hisher} seed flowing in you.`;
  546. }
  547. }
  548. } else {
  549. avatar.activity += `${leader.YouName} overwhelmed from lust. ${leader.YouHeShe} spread legs for ${avatar.himher} and get fucked.`;
  550. eatStatNut(leader,"submissiveness",3);
  551. eatStatNut(rival,"submissiveness",-5);
  552. if (!player.isPregnant()) {
  553. prob2 = (player.maternalism + 50) - getRandomInt(50, 100);
  554. if (prob2 > 0) {
  555. player.pregnancy = 2.5;
  556. player.impregnator=leader;
  557. avatar.activity += `${leader.YouName} overwhelmed from lust. ${leader.YouHeShe} spread legs for ${avatar.himher} to get fucked. ${avatar.HeShe} push deep inside. ${leader.YouHeShe} moan like shebeast, as ${avatar.hisher} seed erupts from cock inside ${leader.youhimher} .`;
  558. }
  559. }
  560. }
  561. };
  562. this.PCfucksNPCvaginal = function (avatar) {
  563. avatar.activity += avatar.HeShe + ` come to ${leader.youName} and spread legs. ${leader.YouHeShe} fuck like beast.`;
  564. if (!this.isPregnant()) {
  565. var prob = this.maternalism - getRandomInt(50, 100);
  566. if (prob > 0) {
  567. this.pregnancy = 2.5;
  568. this.impregnator=leader;
  569. avatar.activity += `${avatar.HeShe} come to ${leader.youName} and spread legs like shebeast in need. ${leader.YouHeShe} fuck like animal and fill ${avatar.himher} with seed.`;
  570. }
  571. }
  572. };
  573. this.confused = function(avatar) {
  574. avatar.activity += "<p>She spend week wandering camp, muttering to self about how she man. Strong man. But she walk more and more like woman. She cry easier and easier like woman. Soon she forget how be man and only be woman for you.</p>";
  575. avatar.dysphoria -= getRandomInt(1, 10);
  576. };
  577. this.tend = function(avatar) {
  578. avatar.activity += `<p>${avatar.HeShe} dutifully tend camp for ${leader.youName}.</p>`;
  579. player.goods+=1;
  580. if(avatar.dysphoria>0){avatar.dysphoria-=getRandomInt(0,2);}
  581. };
  582. this.fuck = function(avatar) {
  583. var activities = avatar.fuckCharacter(leader);
  584. var prelude = `${avatar.YouName} come to ${leader.youName} at night full of desire. `;
  585. this.activity = prelude+activities[0];
  586. leader.doneTo =prelude+activities[1];
  587. //avatar.activity += `<p>${avatar.HeShe} come to ${leader.youName} every night and spread legs. ${leader.YouHeShe} fuck like animal.</p>`;
  588. //avatar.fornicate();
  589. };
  590. this.detectTrap = function(avatar,difficulty){
  591. var scoreT = this.perception()+this.domesticity-50+player.cunning();
  592. var scoreA = difficulty*(avatar.domesticity-30+ avatar.cunning()+avatar.perception()+getRandomInt(-70,70));
  593. console.log(scoreT,scoreA);
  594. return scoreT>scoreA;
  595. };
  596. this.offerTrap = function(avatar){
  597. avatar.activity+=`</p>${avatar.HeShe} found some nuts while foraging. ${avatar.HeShe} has offered it to ${leader.youName} as a meal.`;
  598. if(leader.detectTrap(avatar,2)){
  599. avatar.activity+=leader.YouHeShe+" have bad feeling, though, so don't eat.";
  600. avatar.naughty=true;
  601. }else {
  602. avatar.activity+=`${leader.YouHeShe} feel weak after eating.`;
  603. if(leader.detectTrap(avatar,0.8)){
  604. avatar.activity+=` ${leader.YouHeShe} think it maybe from bad food ${avatar.name} give ${leader.youhimher}.`;
  605. avatar.naughty=true;
  606. }
  607. var stat = getRandomElem(["submissiveness","domesticity","allure","orientation","maternalism"]);
  608. var amount = getRandomInt(1,6);
  609. leader.changeNatural(stat,amount);
  610. leader[stat]+=amount;
  611. }
  612. avatar.activity+="</p>"
  613. };
  614. this.bolsterSelf = function(avatar){
  615. avatar.activity+=`<p>${avatar.HeShe} forage for food outside camp. Find nut to eat.`;
  616. if(leader.detectTrap(avatar,0.8)){
  617. avatar.activity+=` ${leader.YouName} notice that ${avatar.youName} more like man after eating.`;
  618. avatar.naughty=true;
  619. }
  620. var stat = getRandomElem(["submissiveness","domesticity","allure","orientation","maternalism"]);
  621. var amount = getRandomInt(-20,-5);
  622. avatar.changeNatural(stat,amount);
  623. avatar[stat]+=amount;
  624. avatar.activity+="</p>";
  625. };
  626. this.forageFood = function(avatar){
  627. if(getRandomInt(-1,Math.floor(avatar.domesticity/15))>0){
  628. avatar.activity += `<p>${avatar.HeShe} look around wild for root and nut and berry. Bring back to camp.</p>`;
  629. leader.goods+=getRandomInt(2,1+Math.floor(avatar.domesticity/15));
  630. }else{
  631. avatar.activity += `<p>${avatar.HeShe} search for food, but return empty.</p>`;
  632. }
  633. };
  634. this.womanForage = function(avatar){
  635. var activity = avatar.forageFood;
  636. if(avatar.dysphoria<=0){
  637. return avatar.forageFood(avatar);
  638. }
  639. var result = avatar.dysphoria+Math.floor(avatar.masculinity()/3)+getRandomInt(1,100);
  640. if(result<70){
  641. avatar.forageFood(avatar);
  642. }else{
  643. var self=0;
  644. var other=1;
  645. if(avatar.dysphoria>10){self-=1;}
  646. if(avatar.masculinity()>avatar.femininity()){other+=1;}else{self-=1;}
  647. if(getRandomInt(self,other)>0){
  648. avatar.offerTrap(avatar);
  649. }else{
  650. avatar.bolsterSelf(avatar);
  651. }
  652. }
  653. };
  654. this.leaderHunt = function(avatar){
  655. var success = Math.max(50,leader.submissiveness+leader.orientation+leader.allure-100);//always default 50% chance of winning
  656. if(getRandomInt(1,100)<success){
  657. avatar.activity = `${avatar.HeShe} go on hunt. Find rival man and fight hard. Drive off and take his changra.`;
  658. eatStatNut(avatar,"submissiveness",getRandomInt(-15,2));
  659. eatStatNut(avatar,"allure",getRandomInt(-15,2));
  660. eatStatNut(avatar,"domesticity",getRandomInt(-15,2));
  661. eatStatNut(avatar,"orientation",getRandomInt(-15,2));
  662. eatStatNut(avatar,"maternalism",getRandomInt(-15,2));
  663. }else{
  664. avatar.activity = `${avatar.HeShe} ambushed on hunt, escape rival before he changed too much`;
  665. eatStatNut(avatar,"submissiveness",getRandomInt(-2,15));
  666. eatStatNut(avatar,"allure",getRandomInt(-2,15));
  667. eatStatNut(avatar,"domesticity",getRandomInt(-2,15));
  668. eatStatNut(avatar,"orientation",getRandomInt(-2,15));
  669. eatStatNut(avatar,"maternalism",getRandomInt(-2,15));
  670. }
  671. };
  672. this.leaderForage = function(avatar){
  673. var success = avatar.perception();
  674. if(getRandomInt(1,100)<success){
  675. avatar.activity += `<br/>${avatar.name} find nut in forest, give to you. Because you ${avatar.hisher} woman, you have no choice but eat. Power of ancestor in nut make you feel even more like woman.`;
  676. player.activity += avatar.activity;
  677. player.dysphoria-=2;
  678. eatStatNut(player,getRandomElem(["submissiveness","domesticity","allure","orientation","maternalism"]),getRandomInt(4,12));
  679. }else{
  680. avatar.activity = `${avatar.HeShe} search for special food, but find nothing.`;
  681. }
  682. };
  683. this.leaderPacify = function(avatar){
  684. target = [...avatar.women.filter(x=>x!==player)].sort((a,b)=>b.masculinity()-a.masculinity())[0];
  685. var targetNum = 21;
  686. if(!target){
  687. return;
  688. }
  689. if(leader.masculinity()-5>target.masculinity()){
  690. targetNum=27;
  691. }
  692. challengedYet = true;
  693. if(getRandomInt(1,30)<targetNum){
  694. challengeResult = `<br/>${avatar.name} think ${target.name} getting too disobedient. Challenge ${target.himher} to fight and show everyone that ${avatar.name} is real clan leader.`;
  695. eatStatNut(target,"submissiveness",getRandomInt(5,70));
  696. eatStatNut(target,"alure",getRandomInt(5,70));
  697. eatStatNut(target,"domesticity",getRandomInt(5,70));
  698. eatStatNut(target,"orientation",getRandomInt(5,70));
  699. eatStatNut(target,"maternalism",getRandomInt(5,75));
  700. target.dysphoria-=getRandomInt(30,70);
  701. leader.women.filter(x=>x!==player).forEach(x=>x.dysphoria=x.dysphoria/1.5-5);
  702. }else{
  703. challengeResult = `<br/>${avatar.name} think ${target.name} too unruly and challenge ${target.himher} to fight. ${target.name} too strong, though, and make ${avatar.name} into woman.`;
  704. avatar.activity = `<br/>${avatar.HeShe} lose challenge and become ${target.name}\'s woman.`;
  705. eatStatNut(leader,"submissiveness",getRandomInt(40,90));
  706. eatStatNut(leader,"alure",getRandomInt(44,90));
  707. eatStatNut(leader,"domesticity",getRandomInt(44,90));
  708. eatStatNut(leader,"orientation",getRandomInt(45,90));
  709. eatStatNut(leader,"maternalism",getRandomInt(45,90));
  710. makeLeader(leader,target,true);
  711. }
  712. };
  713. this.fuckCharacter = function(target,forced){/*this is getting big enough that it should maybe go to its own file.*/
  714. return initiateSex(this,target,forced)
  715. }
  716. this.fuckPlayer = function(avatar){
  717. var activities = avatar.fuckCharacter(player,false);
  718. var activity = activities[0];
  719. var playerActivity = activities[1];
  720. var intro = getRandomElem([
  721. `${avatar.name} come to you wanting to fuck. `,
  722. `${avatar.name} come say ${avatar.heshe} want fuck. `,
  723. `${avatar.name} get horny and summon you to ${avatar.hisher} tent. `,
  724. ]);
  725. player.dysphoria-=6;
  726. player.doneTo+="<p>"+intro+playerActivity+"</p>";
  727. avatar.activity+="<p>"+intro+activity+"</p>";
  728. return
  729. avatar.desire=0;
  730. var activity;
  731. var type = "other";
  732. var playerFucked = true;
  733. var leaderFucked = false;//if female leaderg fucked by male player.
  734. var mL = leader.isMale();
  735. var mP = player.isMale();
  736. var diff = (player.submissiveness-leader.submissiveness);
  737. if((diff>30)&&(player.submissiveness>60)){
  738. type = "sub";
  739. }else if((diff<-30)&&(player.submissiveness<40)){
  740. type="dom";
  741. }
  742. if(player.dysphoria>150){/*
  743. switch(type){
  744. case "dom":
  745. if((diff>60)){
  746. activity = `<p>${avatar.name} come wanting to fuck you, but back down when you refuse.</p>`;
  747. player.dysphoria+=5;
  748. playerFucked=false;
  749. }else{
  750. if(mP){
  751. activity = `<p>${avatar.name} come wanting to fuck. You tell ${avatar.himher} to get on ground then. ${avatar.name} argue, saying ${avatar.heshe} clan leader, but ${avatar.heshe} timid and soon back down. Soon you fucking ${avatar.himher} from behind until ${avatar.heshe} scream in climax</p>`;
  752. playerFucked=false;
  753. if(!mL){
  754. leaderFucked=true;
  755. }
  756. player.dysphoria+=10;
  757. eatStatNut(leader,"orientation",5);
  758. eatStatNut(leader,"submissiveness",3);
  759. }else if(!mP && !mL){//ff
  760. activity = `<p>${avatar.name} ask to fuck. Very soon ${leader.himher} head buried between your legs. It feel good when ${avatar.name}\'s tongue lick you.</p>`;
  761. }else{ //fm
  762. activity = `<p>${avatar.name} come wanting fuck. You argue, saying you not woman, but he point and say your body is woman body. Eventually you agree, but only if you on top. You ride up and down on ${avatar.name}\'s cock, surprised that it feel so good. Being on top make you feel big and powerful, it only when his seed dribble down leg that you realize you still fucked as woman.</p>`;
  763. eatStatNut(player,"submissiveness",-2);
  764. }
  765. }
  766. break;
  767. case "sub":
  768. if(mL){
  769. activity = `<p>${avatar.name} get horny and demand you fuck. You want protest that you not really woman, but ${avatar.heshe} clan leader. You just weak and timid
  770. }
  771. }
  772. if(dom>35){
  773. activity = `${avatar.name}`
  774. } */
  775. avatar.activity += `<br/>${avatar.name} tell you he want fuck. You cry and say you not woman, but he point and say your body is woman body. Because he is powerful clan leader, you do what he say and let him fuck you like woman. As he does, you feel shame because your body acts like woman body, feel like woman body, respond to clan leader touch, making you wonder if you will ever be man again.`;
  776. }else if(player.dysphoria>35){
  777. avatar.activity += `<br/>${avatar.name} come tell you to spread legs. As you fuck, you think maybe not so bad to be woman.`;
  778. }else{
  779. avatar.activity += `<br/>When ${avatar.name} come for fuck, you are very happy. It feel very good to be fucked like woman by clan leader.`;
  780. }
  781. if(playerFucked){
  782. eatStatNut(player,getRandomElem(["allure","maternalism","orientation"]),getRandomInt(3,7));
  783. avatar.activity+=activity;
  784. player.activity+=activity;
  785. player.maybeImpregnate(rival);
  786. player.dysphoria-=5;
  787. }
  788. };
  789. this.compareMods = function(defender){
  790. return (this.pushsubmissiveness+this.pushdomesticity+this.pushorientation+this.pushallure+this.pushmaternalism-defender.resistsubmissiveness-defender.resistdomesticity-defender.resistorientation-defender.resistallure-defender.resistmaternalism);
  791. };
  792. this.compareMod = function(defender,stat){
  793. var ret = Math.pow(1.25,this.Mods["push"+stat]-defender.Mods['resist'+stat]);
  794. console.log(this.name,defender.name,stat,this.Mods["push"+stat],defender.Mods['resist'+stat],ret);
  795. return ret;
  796. };
  797. this.compareStat = function(defender,stat){
  798. var ret= (getRandomInt(0,this.compareMod(defender,stat)*this[stat]) - getRandomInt(defender.compareMod(this,stat)*defender[stat],0));
  799. console.log(stat,ret);
  800. return ret;
  801. };
  802. this.challengeLeader = function(avatar){
  803. challengedYet=true;
  804. console.log("Challengeing leader");
  805. if(leader===player){
  806. avatar.challengePlayer(avatar);
  807. return;
  808. }
  809. var rawScore = AVATAR_TRAITS.map((s)=>leader.compareStat(avatar,s)).reduce( (x,s)=>x+s,0);
  810. var lScore = rawScore-getRandomInt(-15,40);//randomize, but bias towards status quo
  811. console.log(rawScore,lScore);
  812. if(lScore>0){
  813. $.each(AVATAR_TRAITS,(index,val)=>{avatar[val]-=getRandomInt(20,55);leader[val]=avatar.desires[val]+getRandomInt(-5,25);});
  814. avatar.activity+=`<br/>${avatar.name} challenge ${leader.name}. ${avatar.HeShe} win challenge and become new leader.`;
  815. leader.activity+=`<br/>${leader.name} lose challenge. He ${avatar.name} woman now.`;
  816. //player.activity+=avatar.activity;
  817. challengeResult=`<br/>${avatar.name} challenge ${leader.name} and defeat ${leader.himher} in front of whole clan. When ${avatar.heshe} done, ${avatar.heshe} use ${leader.name} like woman while everyone watch. Now ${avatar.name} Clan Father.`;
  818. makeLeader(leader,avatar,true);
  819. }else{
  820. $.each(AVATAR_TRAITS,(index,val)=>{leader[val]-=getRandomInt(5,20);avatar[val]=leader.desires[val]+getRandomInt(-5,25);});
  821. avatar.dysphoria/=2;
  822. avatar.dysphoria-=25;
  823. avatar.activity+=`<br/>${avatar.HeShe} try challenge ${leader.name}, but lose fight.`;
  824. challengeResult = `<br/>${avatar.name} think ${avatar.heshe} strong enough to beat ${leader.name} and become new clan leader, but ${avatar.heshe} wrong. After fight is done, ${leader.name} throw ${avatar.name} to dirt and show everyone who is true woman.`;
  825. }
  826. };
  827. this.seduceWoman = function(targets){
  828. return function(avatar){
  829. var target = getRandomElem(targets);
  830. avatar.desire=0;
  831. target.desire=0;
  832. target.dysphoria -= getRandomInt(0,Math.round(100-target.orientation)/4);
  833. var activity = `<br/>${avatar.YouName} decide to show ${target.youName} how good it feel to have woman body. Make ${target.youhimher} scream many time, until ${target.youheshe} think maybe it good thing to be woman.`;
  834. avatar.activity += activity;
  835. target.doneTo +=activity;
  836. };
  837. };
  838. this.teachWoman = function(targets){
  839. return function(avatar){
  840. var target = getRandomElem(targets);
  841. target.dysphoria -= getRandomInt(1,4);
  842. eatStatNut(target,"domesticity",getRandomInt(1,5));
  843. var activity = `<br/>${avatar.name} come to ${target.youName} and teach ${target.youhimher} how to be better at women work.`;
  844. avatar.activity += activity;
  845. target.dontTo += activity;
  846. };
  847. };
  848. this.disciplineWoman = function(targets){
  849. return function(avatar){
  850. var target = getRandomElem(targets);
  851. target.dysphoria -= getRandomInt(4,30);
  852. eatStatNut(target,"submissiveness",getRandomInt(1,5));
  853. var activity = `<br/>${avatar.name} notices ${target.youName} acting out. ${avatar.HeShe} spank ${target.youName} until ${target.youheshe} agree to behave like good woman.`;
  854. avatar.activity+=activity;
  855. target.doneTo +=activity;
  856. };
  857. };
  858. this.teachFuck = function(targets){
  859. return function(avatar){
  860. var target =getRandomElem(targets);
  861. target.dysphoria -=getRandomInt(1,6);
  862. eatStatNut(target,"orientation",getRandomInt(1,3));
  863. var protest;
  864. if(target.dysphoria>60){
  865. protest= `${target.YouHeShe} beg and plead, but ${avatar.name} no listen. S`;
  866. }else if(target.dysphoria>20){
  867. protest = `${target.YouHeShe} protest, but s`;
  868. }else{
  869. protest="S";
  870. }
  871. var activity = `<br/>${avatar.name} come to ${target.youName} at night. "${target.name}! You woman now. Time learn how womanfolk fuck." ${protest}he bring ${target.youheshe} to ${leader.name} and teach ${target.youhimher} to pleasure a man.`;
  872. avatar.activity+=activity;
  873. target.doneTo += activity;
  874. };
  875. };
  876. this.flirtWoman = function(targets){
  877. return function(avatar){
  878. var target= getRandomElem(targets);
  879. if(target){
  880. var flirtAction = avatar.allure<35?"flex muscles":"bat eyelashes";
  881. var flirtResult = "";
  882. if(avatar!==leader){
  883. var score = getRandomInt(0,6)+4*(avatar.submissiveness<50)+4*(avatar.allure<50)+4*(avatar.maternalism<50);
  884. if((score>=10)&&(target.isFemale())){
  885. flirtResult = `Loving womanfolk is nice, ${avatar.youheshe} think. Would be good to be clan leader and have many women.`;
  886. avatar.dysphoria+=10;
  887. }else{
  888. flirtResult = `${avatar.YouHeShe} all warm and happy from flirt. It nice to be woman.`;
  889. avatar.dysphoria-=1;
  890. }
  891. }else{
  892. }
  893. var activity = `<br/>${avatar.YouName} smile at ${target.youName} and ${flirtAction} at ${avatar.youhimher}. ${flirtResult}`
  894. eatStatNut(avatar,"orientation",target.isMale()?3:-3);
  895. eatStatNut(target,"orientation",avatar.isMale()?1:-1);
  896. avatar.activity+=activity;
  897. target.doneTo+=activity;
  898. }
  899. };
  900. };
  901. this.complainToOther = function(targets){
  902. return function(avatar){
  903. var target = getRandomElem(targets);
  904. avatar.dysphoria += getRandomInt(1,3);
  905. if((target===thoth)&&(avatar===player)){
  906. if(thoth.reactionProgress<4){
  907. response = `"It be ok, ${player.maleName}," ${thoth.name} say, "Soon you get strong and become clanfather again. Then everything will be good again.`;
  908. avatar.dysphoria+=4;
  909. }else if(thoth.reactionProgress<5){
  910. response = `"Why you complain, ${player.maleName}?" ${thoth.name} ask, "If you not want be bred like woman, then maybe you should become leader again?`;
  911. }else{
  912. response = `"Stop complaining!" ${thoth.name} say. "You had chance to be leader, but now you exactly what you supposed to be, ${leader.yourNames} woman. So shut mouth, spread legs, and get baby for clan like the good breeder you are."`;
  913. avatar.dysphoria-=6;
  914. }
  915. avatar.activity=response;
  916. }else if(target){
  917. var rScore = target.dysphoria+getRandomInt(-25,50);
  918. var response;
  919. if(rScore<0){
  920. response = `${target.YouHeShe} scold ${avatar.youhimher}, telling ${avatar.youhimher} to be better woman for ${leader.name}. ${target.YouHeShe} then go tell ${leader.youName} what ${avatar.youName} said.`;
  921. target.dysphoria-=2;
  922. avatar.naughty;
  923. avatar.dysphoria-=getRandomInt(1,6);
  924. }else if(rScore<20){
  925. response = `${target.YouName} talk about how good it feel to be woman.`;
  926. target.dysphoria-=2;
  927. avatar.dysphoria-=getRandomInt(1,4);
  928. }else if(rScore<35){
  929. response = `${target.YouHeShe} no listen`;
  930. }else if(rScore<45){
  931. response = `${target.YouHeShe} not agree, but think about words.`;
  932. target.dysphoria+=getRandomInt(0,2);
  933. }else if(rScore<75){
  934. response = `${target.YouHeShe} agree.`;
  935. target.dysphoria+=getRandomInt(1,5);
  936. avatar.dysphoria+=1;
  937. }else{
  938. response = `${target.YouHeShe} agree loudly, saying that ${target.youheshe} not happy being treated like woman.`;
  939. target.dysphoria+=getRandomInt(2,16);
  940. avatar.dysphoria+=getRandomInt(3,7);
  941. }
  942. var activity = `<br/>${avatar.YouName} go to ${target.youName} and complain about becoming womanfolk of clan. ${response}`;
  943. avatar.activity +=activity;
  944. target.doneTo+=activity;
  945. }else{
  946. avatar.activity+=`<br/>${avatar.YouName} complain to anyone who listen, saying ${avatar.youheshe} unhappy being woman.`;
  947. avatar.dysphoria+=getRandomInt(0,3);
  948. }
  949. };
  950. };
  951. this.rabbleRouse = function(avatar){
  952. var target = getRandomElem(leader.women.filter(x=>x!=avatar));
  953. if(target){
  954. avatar.naughty=true;
  955. var activity = `<br/>${avatar.name} not happy being clan woman. ${avatar.HeShe} come to ${target.youName} and convince ${target.youhimher} that ${leader.youName} not good leader.`;
  956. target.dysphoria += getRandomInt(5,20);
  957. avatar.dysphoria += getRandomInt(2,9);
  958. avatar.activity +=activity;
  959. target.doneTo+=activity;
  960. }
  961. };
  962. this.challengePlayer = function(avatar){
  963. rival=avatar;
  964. console.log("challenging player");
  965. console.log(rival);
  966. console.log("leader is player",leader===player, avatar.masculinity(),player.masculinity());
  967. //rival must be more masculine than player.
  968. //must have cock
  969. //must have low enough submissiveness
  970. if(leader===player && (avatar.masculinity()>50)&&rival.hasCock()&&rival.submissiveness<50){
  971. console.log("Doing challenge");
  972. showCamp=false;
  973. //npc tries to switch roles.
  974. //$("#rcwomen").show();
  975. function pretendSubmit(){
  976. makeLeader(player,rival,true,getUnusedFemaleName());
  977. player.maybeImpregnate(rival);
  978. player.dysphoria=3*player.masculinity()+30*player.Mods.ironwill;
  979. player.orientation=Math.max(50,player.orientation);
  980. player.submissiveness=Math.max(50,player.submissiveness);
  981. player.domesticity=Math.max(50,player.domesticity);
  982. player.allure=Math.max(50,player.allure);
  983. Message(NextWindow,`<p>You no want be woman, but ${rival.name} too strong for you to fight. You tell ${rival.name} that you woman now, he man, but you not really mean it.</p><p>He bring you to center of camp, throw you to dirt and show everyone that he man now, you just his woman. Soon, he enter and fuck you wild, make you cry out like deer in heat. He bellow loud like powerful beast. It make you feel strange. You think of babies now, maybe want become clan mother.<p><p>But you strong, you rememember how it feels to be man. You no stay woman, you become big strong man again. But first, must be patient.</p><p>And maybe get fucking from rival again too.</p>`);
  984. EndRound();
  985. }
  986. function doFight(){
  987. var challengeVictory = function(){
  988. rival.submissiveness=100;
  989. Message(NextWindow,"<p>You unleash your changra as "+rival.name+" falls in defeat, no longer able to resist. You show her that she is weak, remind her who is leader of Clan. Soon she forget all about wanting to fight and remember that she belong to you.</p>");
  990. EndRound();
  991. }
  992. var challengeDefeat = function(){
  993. makeLeader(player,rival,true,getUnusedFemaleName());
  994. Message(NextWindow,"<p>"+rival.name+" changra too strong for you. He laugh hearty as he absorb the last of your changra. You collapse like weak little girl at his feet. You no more fight. He too big and powerful. He strong man and you just his woman now.</p>\
  995. <p>He bring you in front of camp and mount you while everyone watches, so everyone knows that he chief and you just another woman. Soon you forget all about becoming chief and man again, want only to be good, obedient woman to powerful chief.</p>");
  996. EndRound();
  997. }
  998. EncounterNamedRival(rival);
  999. rival.Victory=challengeVictory;
  1000. rival.Defeat = challengeDefeat;
  1001. $(".stats").show();
  1002. Battle(rival,false);
  1003. }
  1004. function actualSubmit(){
  1005. var otherwomen="";
  1006. if(player.women.length>1){
  1007. otherwomen="<p>He bring you in front of clan, show you to all of the clan womenfolk. They confused, not understanding, but when he claims you as his woman, they begin to understand that they are all his women now. Just like you.</p>";
  1008. }
  1009. Message("location.reload()","<h1>"+rival.name+" Camp</h1>\
  1010. <p>You no want fight. He big, powerful man, you little woman. When you submit, he turn you over and mount you like she-beast, making you how with pleasure as he takes you hard. Soon, all thought of becoming man or clan leader melts away, until all you think is woman thoughts.</p>"+otherwomen);
  1011. }
  1012. var options = {
  1013. "pretend_button":{
  1014. text:"Pretend Submit",
  1015. action:pretendSubmit
  1016. },
  1017. "fight_button_fight":{
  1018. text:"Fight!",
  1019. action:doFight
  1020. }
  1021. }
  1022. var msg = "<p>You not call "+rival.name+" for fucking, but he come to you at night anyway.</p><p>'"+
  1023. player.name+"!', he say. 'I strong, you weak. I man, you woman. You no lead clan. You be my woman now!</p>\
  1024. <p>You feel weak, confused. Head swims and make your thoughs full of giving him many babies. He steps forward, to mount you and breed you as his womanfolk. If you do not fight him, he will take clan and women, and make them his.</p>";
  1025. if(player.submissiveness>55){
  1026. msg+="<p>He so strong, powerful. Make you feel weak and uncertain. Maybe you want become his womanfolk. Become part of his new clan, get bred with many strong sons like good clan mother.";
  1027. options.submit_button = {
  1028. text:"Submit",
  1029. action:actualSubmit
  1030. }
  1031. }
  1032. ChoiceMessage(msg,rival.name+" Visits",options);
  1033. }else{//backed down from high submissiveness, but will decrease for making the attempt.
  1034. eatStatNut(avatar,"submissiveness",-7);
  1035. challengedYet=false;
  1036. }
  1037. };
  1038. this.gossip = function(targets){
  1039. return function(avatar){
  1040. var target = getRandomElem(targets);
  1041. if (target){
  1042. avatar.activity+=`<br/>${avatar.name} spend time talking with ${target.youName}`;
  1043. }
  1044. }
  1045. };
  1046. this.leaderPiercePlayer = function(craftTargets){
  1047. return function(avatar){
  1048. if(craftTargets.length>0){
  1049. //showCamp=false;
  1050. var target = getRandomElem(craftTargets);
  1051. var desc = "";
  1052. switch(target){
  1053. case "nipplerings":
  1054. desc = "a pair of nipple rings through your womanly teats.";
  1055. player.items.nipplerings=1;
  1056. player.changeNatural("orentation",5);
  1057. player.orientation+=5;
  1058. break;
  1059. case "collar":
  1060. desc = "a lovely collar around your neck, to show the world you belong to him.";
  1061. player.items.collar=1;
  1062. player.changeNatural("submissiveness", 5);
  1063. player.submissiveness += 5;
  1064. break;
  1065. case "headband":
  1066. desc = "an alluring headband.";
  1067. player.items.headband=1;
  1068. player.changeNatural("allure",5);
  1069. player.allure+=5;
  1070. break;
  1071. case "bellybuttonstud":
  1072. desc = "a pretty stud in your bellybutton, to draw attention to your "+(player.isPregnant()?"pregnant":"fertile")+" belly.";
  1073. player.items.bellybuttonstud=1;
  1074. player.changeNatural("maternalism",5);
  1075. player.maternalism+=5;
  1076. break;
  1077. case "clitcockring":
  1078. desc = "a cute piercing in your clit.";
  1079. player.items.clitcockring=1;
  1080. player.changeNatural("orientation",5);
  1081. player.orientation+=5;
  1082. break;
  1083. default:
  1084. desc = "some womanly jewelry.";
  1085. break;
  1086. }
  1087. player.calcPhysique();
  1088. rival=leader;
  1089. redraw();
  1090. var msg = `${leader.name} decides you would look better with ${desc}`;
  1091. player.activity +="<br/>"+msg;
  1092. leader.activity+=msg;
  1093. Message(NextWindow,`<h1>Pierced</h1><p>${msg}</p>`);
  1094. }
  1095. }
  1096. };
  1097. this.setActivity = function() {
  1098. var cannotChallenge = challengedYet||this.dysphoria<=0;
  1099. var mascMult = -1;
  1100. var weeks = player.round-this.round;
  1101. if(leader.isMale()){mascMult-=0.25;}//easier to avoid challenge if you are male
  1102. if(this.isMale()){mascMult+=0.5;}//much more likely to chalenge if they are male
  1103. var seduceTargets = leader.women.filter(x=>(x!==this) && (x.orientation<60)&&(x.dysphoria>10)&&(x.desires.allure<this.allure || this.allure>50) && (!x.isMale()));
  1104. var canSeduce = this.dysphoria<=1 && seduceTargets.length>0;
  1105. var teachTargets = leader.women.filter(x=>x!==this && (this.domesticity -x.domesticity)>=10);
  1106. var canTeach = this.dysphoria<=1 && teachTargets.length>0 && domesticity>50;
  1107. var disciplineTargets = leader.women.filter(x=> x!==this && x.submissiveness>35 && x.submissiveness>this.submissiveness && x.dysphoria>15);
  1108. var canDiscipline = this.submissiveness<=40 && this.dysphoria<=0 && disciplineTargets.length>0;
  1109. var canRabbleRouse = this.dysphoria>10 && this.submissiveness<50;
  1110. var teachFuckTargets = leader.women.filter(x=>x.dysphoria>15);
  1111. var canTeachFuck = (teachFuckTargets.length>0)&&(this.dysphoria<1)&&(this.desire>20)&&(this.allure>50)&&(!leader.isFemale());
  1112. var pierceTargets = jewelryMods.filter(x=>player.Mods["craft"+x]>0 && player.items[x]<1);
  1113. var canPierce = (pierceTargets.length>0);
  1114. var pacifyTargets = leader.women.filter(x=>(x!==player)&&(x.isMale() || x.masculinity>45)&&(x.dysphoria>5));
  1115. var canPacify = pacifyTargets.length>0
  1116. var probs = [
  1117. { action: this.confused, prob: this.dysphoria>10?getRandomInt(-25,40)-10*(weeks>2)-15*(weeks>10):-29 },
  1118. { action: this.tend, prob: getRandomInt(-25, 25)-12*(this.dysphoria>10)-20*(this.dysphoria>60)+3*(this.domesticity>50)+7*(this.domesticity>75) },
  1119. { action: this.womanForage, prob:(this.allowForage?30*(player.goods<10)+10*(player.goods<30)+getRandomInt(-25,25)+8*(this.domesticity>60)/*(this.domesticity+(30*(player.goods<10))+this.dysphoria/2+getRandomInt(-25,25))*/:-30)},
  1120. { action: this.challengeLeader, prob:(cannotChallenge?-35:mascMult*leader.masculinity()+this.masculinity()+getRandomInt(0,this.dysphoria)+getRandomInt(-25,10))},//bias against. should be rareish,
  1121. /* { action:this.offerTrap, prob:(this.masculinity()/5+this.unpredictability*this.dysphoria/2+getRandomInt(-25,25))*(player.round-this.round>10)},
  1122. { action:this.bolsterSelf, prob:(this.femininity()/5+this.unpredictability*this.dysphoria/2+getRandomInt(-25,25))*(player.round-this.round>10)}*/
  1123. ];
  1124. if(this===leader){
  1125. probs = [
  1126. {action:this.leaderHunt,prob:getRandomInt(-25,25)},
  1127. {action:this.leaderForage, prob:getRandomInt(-25,35)},
  1128. {action:this.fuckPlayer,prob:Math.floor(leader.desire/5)+getRandomInt(-25,25)},
  1129. {action:this.leaderPacify,prob:canPacify?getRandomInt(-25,25):-33},
  1130. {action:this.leaderPiercePlayer(pierceTargets), prob:(canPierce?getRandomInt(-30,10):-36)},//placeholder, lower prob once tested.
  1131. ];
  1132. }
  1133. var thothFuck = (this!==thoth || leader===player || thoth.progress>4);
  1134. socialProbs = [
  1135. { action: this.fuck, prob: (this!==thoth || leader===player || thoth.reactionProgress>4)?this.desire/6 + getRandomInt(-25, 30*(this==thoth&&thoth.reactionProgress>4)):-30, choice:"fuck"},//thoth should avoid fucking leader until the thoth story progresses. After that she should be more likely than most
  1136. { action: this.seduceWoman(seduceTargets), prob:canSeduce?getRandomInt(-25,25):-32, choice:"seduce"},
  1137. {action: this.teachWoman(teachTargets), prob:canTeach?getRandomInt(-25,25):-30, choice:"teach"},
  1138. {action: this.disciplineWoman(disciplineTargets),prob:canDiscipline?getRandomInt(-25,25):-33, choice:"discipline"},
  1139. {action: this.rabbleRouse, prob:(canRabbleRouse?getRandomInt(-25,25)+this.submissiveness/10:-35),choice:"rabbleRouse"},
  1140. {action:this.gossip(leader.women.filter(x=>x!=this)), prob:getRandomInt(-25,15), choice:"gossip"},
  1141. {action:this.complainToOther(leader.women.filter(x=>x!=this)), prob:(this.dysphoria>5?getRandomInt(-25,25):-30), choice:"complain"},
  1142. {action:this.teachFuck(teachFuckTargets), prob:(canTeachFuck?getRandomInt(-25,25):-33), choice:"teachFuck"},
  1143. ];
  1144. probs = probs.sort(function(a,b) {
  1145. return b.prob - a.prob;
  1146. });
  1147. //console.log(probs);
  1148. probs[0].action(this);
  1149. if(this!==leader){
  1150. socialProbs=socialProbs.sort((a,b)=>b.prob-a.prob);
  1151. console.log(socialProbs[0]);
  1152. this.socialActivity=socialProbs[0].choice;
  1153. socialProbs[0].action(this);
  1154. }
  1155. };
  1156. // Physique
  1157. this.calcTestes = function(nb) {
  1158. var val = (this.submissiveness + this.domesticity + this.maternalism*4 + this.allure*2)/40;
  1159. if (this.Mods.balls > 0 && nb !== false) val = val > 0 ? this.Mods.balls * -2 : (val + this.Mods.balls * -2);
  1160. return val;
  1161. };
  1162. this.calcPhysique = function() {
  1163. this.getSubmissiveness = function() {
  1164. if (this.futa > 0 && this.submissiveness < 49) return this.submissiveness + 50;
  1165. return this.submissiveness;
  1166. };
  1167. this.getAllure = function() {
  1168. if (this.futa > 0 && this.allure < 49) return this.allure + 50;
  1169. return this.allure;
  1170. };
  1171. this.getDomesticity = function() {
  1172. if (this.futa > 0 && this.domesticity < 49) return this.domesticity + 50;
  1173. return this.domesticity;
  1174. };
  1175. this.getMaternalism = function() {
  1176. if (this.futa > 0 && this.maternalism < 49) return this.maternalism + 50;
  1177. return this.maternalism;
  1178. };
  1179. this.getOrientation = function() {
  1180. if (this.futa > 0 && this.orientation < 49) return this.orientation + 50;
  1181. return this.orientation;
  1182. };
  1183. this.calcHeight = function() {
  1184. if (this.futa > 0 || this.femininity() > 49) return maxValue(20 - (this.submissiveness/5) + this.Mods.amazon, 20);
  1185. return maxValue(20 - (this.getSubmissiveness()/5), 20);
  1186. };
  1187. this.calcFace = function() {
  1188. return ((this.getAllure() * 2) + this.getSubmissiveness())/10;
  1189. };
  1190. this.calcEyes = function() {
  1191. return ((this.getSubmissiveness() * 2) + this.getAllure())/10;
  1192. };
  1193. this.calcLips = function() {
  1194. return (this.getAllure() * 3)/10;
  1195. };
  1196. this.calcHairLength = function() {
  1197. return ((this.getAllure() * 2) + this.getDomesticity())/10;
  1198. };
  1199. this.calcShoulders = function() {
  1200. var val = ((this.getSubmissiveness() * 1.5) + (this.getDomesticity() * 1.5) )/10;
  1201. if (this.femininity() > 49 || this.futa > 0) val = val - (this.Mods.amazon * 4);
  1202. if (val < 0) val = 0;
  1203. return val;
  1204. };
  1205. this.calcBreasts = function() {
  1206. var val;
  1207. if (this.isFutanari() || this.femininity() > 49) val = ((((this.getAllure() + this.Mods.breasts) - 50) * 4) + (((this.getMaternalism() + this.Mods.breasts) - 50) * 2 ))/10;
  1208. else val = (((this.getAllure() - 50) * 4) + ((this.getMaternalism() - 50) *2))/10;
  1209. return minValue(val, 0);
  1210. };
  1211. this.calcNipples = function() {
  1212. var val = (((this.getMaternalism() - 50) * 4) + ((this.getAllure() - 50) *2 ))/10;
  1213. return minValue(val, 0);
  1214. };
  1215. this.calcPenis = function() {
  1216. return (this.orientation + this.allure + this.submissiveness)/10;
  1217. };
  1218. this.calcWaist = function() {
  1219. return ((this.getAllure() * 3) - this.pregnancy * 5)/10;
  1220. };
  1221. this.calcHips = function() {
  1222. return (this.getMaternalism() * 3)/10;
  1223. };
  1224. this.calcAss = function() {
  1225. return ((this.getMaternalism() * 2) + this.getAllure())/10;
  1226. };
  1227. this.calcLegs = function() {
  1228. return ((this.getDomesticity() * 2) + this.getAllure())/10;
  1229. };
  1230. this.capTraits();
  1231. this.physique.height = this.calcHeight();
  1232. this.physique.face = this.calcFace();
  1233. this.physique.eyes = this.calcEyes();
  1234. this.physique.lips = this.calcLips();
  1235. this.physique.hairlength = this.calcHairLength();
  1236. this.physique.shoulders = this.calcShoulders();
  1237. this.physique.breasts = this.calcBreasts();
  1238. this.physique.nipples = this.calcNipples();
  1239. this.physique.testes = this.calcTestes();
  1240. this.physique.penis = this.calcPenis();
  1241. this.physique.waist = this.calcWaist();
  1242. this.physique.hips = this.calcHips();
  1243. this.physique.ass = this.calcAss();
  1244. this.physique.legs = this.calcLegs();
  1245. };
  1246. // Traits
  1247. this.capTraits = function()
  1248. {
  1249. $.each(AVATAR_TRAITS, function( index, trait ) {
  1250. that[trait] = minValue(that[trait], -4);
  1251. that.minimums[trait] = minValue(that.minimums[trait], -4);
  1252. that.minimums[trait] = maxValue(that.minimums[trait], 100);
  1253. that.natural[trait] = minValue(that.natural[trait], -4);
  1254. that[trait] = maxValue(Math.floor(that[trait]), 100);
  1255. that.maximums[trait] = minValue(Math.floor(that.maximums[trait]), -4);
  1256. that.maximums[trait] = maxValue(Math.floor(that.maximums[trait]), 100);
  1257. that.natural[trait] = maxValue(Math.floor(that.natural[trait]), 100);
  1258. });
  1259. that.changra = minValue(that.changra, 0);
  1260. that.changra = Math.floor(maxValue(that.changra, 120 + that.Mods.changra + (that.women.length / 2) - that.femininity()));
  1261. };
  1262. // Initialise
  1263. this.calcPhysique();
  1264. $.each(AVATAR_TRAITS, function(index, trait) {
  1265. that.natural[trait] = that[trait];
  1266. that.minimums[trait] = that[trait] - 15;
  1267. that.maximums[trait] = that[trait] + 35;
  1268. });
  1269. // Rival details
  1270. // Unused for player or their women
  1271. this.desires = {
  1272. "submissiveness": getRandomInt(35, 95),
  1273. "domesticity": getRandomInt(35, 95),
  1274. "maternalism": getRandomInt(35, 95),
  1275. "allure": getRandomInt(35, 95),
  1276. "orientation": getRandomInt(50, 95)
  1277. };
  1278. this.dysphoria = this.masculinity();
  1279. this.pushPreference = getRandomInt(0, 2);
  1280. this.drainPreference = getRandomInt(0, 2);
  1281. this.reflectPreference = getRandomInt(0, 1);
  1282. var preferenceDifference = differenceBetween(this.pushPreference, this.drainPreference);
  1283. this.unpredictability = getRandomInt(preferenceDifference, preferenceDifference + 2);
  1284. this.offensiveness = getRandomInt(0, 10);
  1285. this.defensiveness = getRandomInt(0, 10);
  1286. this.currentAction = "";
  1287. // Combat functions
  1288. this.Victory = function() { };
  1289. this.Defeat = function() { };
  1290. this.spendExperience = function() { };
  1291. this.getTell = function(action) { };
  1292. this.getRecognise = function() {
  1293. if (this.round > 0) return "you recognise him, he is " + this.name;
  1294. return "";
  1295. }
  1296. this.determineAttackTrait = function(avatar, opponent, action) {return "submissiveness";}
  1297. // Save/Load
  1298. this.upgradeSave = function()
  1299. {
  1300. // Following needed to upgrade save games
  1301. if (isNaN(that.Mods.changra)) that.Mods.changra = 0;
  1302. if (isNaN(that.Mods.breasts)) that.Mods.breasts = 0;
  1303. if (isNaN(that.Mods.perception)) that.Mods.perception = 0;
  1304. if (isNaN(that.Mods.amazon)) that.Mods.amazon = 0;
  1305. if (isNaN(that.Mods.cock)) that.Mods.cock = 0;
  1306. if (isNaN(that.Mods.futa)) that.Mods.futa = 0;
  1307. if (isNaN(that.Mods.balls)) that.Mods.balls = 0;
  1308. if (isNaN(that.Mods.infuse)) that.Mods.infuse = 0;
  1309. if (isNaN(that.Mods.craftnipplerings)) that.Mods.craftnipplerings = 0;
  1310. if (isNaN(that.Mods.craftclitcockring)) that.Mods.craftclitcockring = 0;
  1311. if (isNaN(that.Mods.craftcollar)) that.Mods.craftcollar = 0;
  1312. if (isNaN(that.Mods.craftheadband)) that.Mods.craftheadband = 0;
  1313. if (isNaN(that.Mods.craftbellybuttonstud)) that.Mods.craftbellybuttonstud = 0;
  1314. if (isNaN(that.Mods.craftleftbracelet)) that.Mods.craftleftbracelet = 0;
  1315. if (isNaN(that.Mods.pushsubmissiveness)) that.Mods.pushsubmissiveness = 0;
  1316. if (isNaN(that.Mods.pushdomesticity)) that.Mods.pushdomesticity = 0;
  1317. if (isNaN(that.Mods.pushmaternalism)) that.Mods.pushmaternalism = 0;
  1318. if (isNaN(that.Mods.pushallure)) that.Mods.pushallure = 0;
  1319. if (isNaN(that.Mods.pushorientation)) that.Mods.pushorientation = 0;
  1320. if (isNaN(that.Mods.ironwill)) that.Mods.ironwill = 0;
  1321. if (isNaN(that.physique.breastrows)) that.physique.breastrows = 0;
  1322. if (isNaN(that.physique.gentialscnt)) that.physique.gentialscnt = 1;
  1323. if (isNaN(that.physique.twins)) that.physique.twins = 5;
  1324. if (isNaN(that.physique.horns)) {
  1325. that.physique.horns = 0;
  1326. that.physique.hornstype = 0;
  1327. }
  1328. if (isNaN(that.physique.tail)) {
  1329. that.physique.tail = 0;
  1330. that.physique.tailtype = 0;
  1331. }
  1332. if (isNaN(that.physique.wings)) that.physique.wings = 0;
  1333. if (isNaN(that.physique.hairstyle)) that.physique.hairstyle = 1;
  1334. if (isNaN(that.Mods.resistsubmissiveness)) that.Mods.resistsubmissiveness = 0;
  1335. if (isNaN(that.Mods.resistdomesticity)) that.Mods.resistdomesticity = 0;
  1336. if (isNaN(that.Mods.resistmaternalism)) that.Mods.resistmaternalism = 0;
  1337. if (isNaN(that.Mods.resistallure)) that.Mods.resistallure = 0;
  1338. if (isNaN(that.Mods.resistorientation)) that.Mods.resistorientation = 0;
  1339. if (isNaN(that.futa)) that.futa = 0;
  1340. //I don't understand why this is set, rather than saved
  1341. /*
  1342. if (that != player) {
  1343. if (that.activity === "") that.setActivity();
  1344. if (that.Mods.futa > 0) {
  1345. that.Mods.cock = that.Mods.futa;
  1346. that.Mods.futa = 0;
  1347. }
  1348. } else {
  1349. if (that.activity.indexOf("birth") == -1) that.activity = "";
  1350. }*/
  1351. if (that.futa > 0 && that.Mods.cock === 0) that.Mods.cock = 1;
  1352. if(that.allowForage===undefined){that.allowForage=false;}
  1353. if (that.name === "") that.name = getUnusedFemaleName();
  1354. if (isNaN(that.pregnancy)) {
  1355. that.pregnancy = 0;
  1356. that.impregnator=false;
  1357. that.childrenboy = 0;
  1358. that.childrengirl = 0;
  1359. } else if (that.pregnancy > 0 && !that.hasVagina()) {
  1360. that.pregnancy = 0;
  1361. }
  1362. if (isNaN(that.childrenboy) || (that["children"] !== undefined && that["children"] !== 0)) {
  1363. that.childrenboy = that["children"];
  1364. if (isNaN(that.childrenboy)) that.childrenboy = 0;
  1365. delete that["children"];
  1366. }
  1367. if (isNaN(that.childrengirl)) that.childrengirl = 0;
  1368. if (isNaN(that.round)) that.round = 0;
  1369. if (isNaN(that.goods)) that.goods = 0;
  1370. if (isNaN(that.metal)) that.metal = 0;
  1371. if (isNaN(that.items.nipplerings)) {
  1372. if (that == smith) that.items.nipplerings = 1;
  1373. else that.items.nipplerings = 0;
  1374. }
  1375. if (isNaN(that.items.collar)) that.items.collar = 0;
  1376. if (isNaN(that.items.headband)) that.items.headband = 0;
  1377. if (isNaN(that.items.bellybuttonstud)) that.items.bellybuttonstud = 0;
  1378. if (isNaN(that.items.clitcockring)) that.items.clitcockring = 0;
  1379. if (isNaN(that.items.leftbracelet)) that.items.leftbracelet = 0;
  1380. if (isNaN(that.switches1)) {
  1381. if (!isNaN(that.switches)) that.switches1 = that.switches;
  1382. if (!isNaN(that.switches1)) that.switches1 = 0;
  1383. // remove duplicate entries
  1384. // Once off fix
  1385. for (var index = 0; index < that.women.length; index++) {
  1386. var wm = that.women[index];
  1387. for (var idx = 0; idx < that.women.length; itx++) {
  1388. if (idx === index) continue;
  1389. if (that.women[idx] === wm) {
  1390. // duplicate entry
  1391. that.women.splice(idx, 1);
  1392. index = -1; // reset to start of loop!
  1393. break;
  1394. }
  1395. }
  1396. }
  1397. }
  1398. };
  1399. this.replaceRefs = function(charTable){
  1400. var tmp = this.women.map(function(woman){
  1401. return charTable.indexOf(woman);
  1402. });
  1403. this.women=tmp;
  1404. if(this.impregnator){
  1405. this.impregnator=charTable.indexOf(this.impregnator);
  1406. }
  1407. };
  1408. this.restoreRefs =function(charTable){
  1409. var tmp = this.women;
  1410. this.women = this.women.map(function(index){
  1411. return charTable[index];
  1412. });
  1413. if(this.impregnator===undefined){
  1414. if(this.pregnancy>0){
  1415. this.impregnator=leader;//just make an assumption. Quite possibly wrong, but best one we can. Only matters for old saves
  1416. }else{
  1417. this.impregnator=false;
  1418. }
  1419. }
  1420. if(this.impregnator!==false){
  1421. this.impregnator=charTable[this.impregnator];
  1422. }
  1423. };
  1424. this.loadGame = function(save,charTable)
  1425. {
  1426. this.women = [];
  1427. for (var i = 0; i < save.women.length; i += 1 ) {
  1428. this.women[i] = new Avatar(50, 95, 90, 75, 80);
  1429. jQuery.extend(this.women[i], save.women[i]);
  1430. this.women[i].upgradeSave();
  1431. }
  1432. this.upgradeSave();
  1433. };
  1434. }