sex.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. const SexFlags = Enum([
  2. "gotPiV",
  3. "gavePiV",
  4. "gaveOral",
  5. "gotOral",
  6. "gotAnal",
  7. "gaveAnal",
  8. "gotFucked",//"generic" fucking that changes depending on participant genders
  9. "didFuck", //will also set the relevant flags between sex and reflection steps.
  10. "gaveHandjob",
  11. "gotHandjob",
  12. "onTop",
  13. "onBottom",
  14. "isSub",
  15. "isDom",
  16. "gotForced",
  17. "didForce",
  18. "isMan",
  19. "isWoman",
  20. "isFuta",
  21. "didSuckCock",
  22. "gotCockSucked",
  23. "didLickPussy",
  24. "gotPussyLicked",
  25. "isPregnant",
  26. ]);
  27. const SexEncounterFlags = Enum([
  28. "iDom",
  29. "rDom",
  30. "mf",
  31. "mm",
  32. "ff",
  33. "futa",
  34. "iHot",
  35. "iUg",
  36. "refused",//successfully refused to fuck
  37. "force",//encounter was forced (generally by leader). Maybe
  38. "wrongO",//target has wrong orientation for initiator
  39. "lp",//leader/player interaction
  40. "reversal",//submissiveness stat is different from leader/follower dynamic
  41. "mDom",//male dominant
  42. "fDom",//female dominant
  43. "fSub",
  44. "mSub",
  45. "fRec",//female recipient
  46. "mRec",
  47. "mInit",//initiator is male
  48. "fInit",
  49. ]);
  50. var sexActs;
  51. var sexReactions;
  52. {
  53. /*Encounter Flags*/
  54. const iDom = SexEncounterFlags.iDom;
  55. const rDom = SexEncounterFlags.rDom;
  56. const mf = SexEncounterFlags.mf;
  57. const mm = SexEncounterFlags.mm;
  58. const ff = SexEncounterFlags.ff;
  59. const futa = SexEncounterFlags.futa;
  60. const iHot = SexEncounterFlags.iHot;
  61. const iUg = SexEncounterFlags.iUg;
  62. const refused = SexEncounterFlags.refused;//successfully refused to fuck
  63. const force = SexEncounterFlags.force;//encounter was forced (generally by leader). Maybe
  64. const wrongO = SexEncounterFlags.wrongO;//target has wrong orientation for initiator
  65. const lp = SexEncounterFlags.lp;//leader/player interaction
  66. const reversal = SexEncounterFlags.reversal;//submissiveness stat is different from leader/follower dynamic
  67. const mDom = SexEncounterFlags.mDom;//male dominant
  68. const fDom = SexEncounterFlags.fDom;//female dominant
  69. const fSub = SexEncounterFlags.fSub;
  70. const mSub = SexEncounterFlags.mSub;
  71. const fRec = SexEncounterFlags.fRec;//female recipient
  72. const mRec = SexEncounterFlags.mRec;
  73. const mInit = SexEncounterFlags.mInit;//initiator is male
  74. const fInit = SexEncounterFlags.fInit;
  75. /*Character Flags*/
  76. const gotPiV = SexFlags.gotPiV;
  77. const gavePiV = SexFlags.gavePiV;
  78. const gaveOral=SexFlags.gaveOral;
  79. const gotOral =SexFlags.gotOral;
  80. const gotAnal =SexFlags.gotAnal;
  81. const gaveAnal =SexFlags.gaveAnal;
  82. const gotFucked=SexFlags.gotFucked;//"generic" fucking that changes depending on participant genders
  83. const didFuck=SexFlags.didFuck; //will also set the relevant flags between sex and reflection steps.
  84. const gaveHandjob=SexFlags.gaveHandjob;
  85. const gotHandjob=SexFlags.gotHandjob;
  86. const onTop=SexFlags.onTop;
  87. const onBottom=SexFlags.onBottom;
  88. const isSub=SexFlags.isSub;
  89. const isDom=SexFlags.isDom;
  90. const gotForced=SexFlags.gotForced;
  91. const didForce=SexFlags.didForce;
  92. const isMan = SexFlags.isMan;
  93. const isWoman = SexFlags.isWoman;
  94. const isFuta = SexFlags.isFuta;
  95. const didSuckCock =SexFlags.didSuckCock;
  96. const gotCockSucked = SexFlags.gotCockSucked;
  97. const didLickPussy = SexFlags.didLickPussy;
  98. const gotPussyLicked=SexFlags.gotPussyLicked;
  99. const isPregnant = SexFlags.isPregnant;
  100. sexActs = [//note:refuseFuck will be added to notags by default if refused is not a tag. Just easier that way
  101. {
  102. minD:50,
  103. tags:rDom|refused,
  104. activity:"{{initiator.YouHeShe}} back down when {{target.youheshe}} refuse",
  105. dys:5,
  106. },
  107. {
  108. notags:rDom,
  109. tags:refused|force,
  110. activity:"{{target.YouHeShe}} run away instead.",
  111. dys:5,
  112. },
  113. {
  114. tags:mf|fDom,
  115. activity:"{{dominant.YouHeShe}} push {{submissive.youName}} down and ride cock hard. {{dominant.YouHeShe}} scream like shebeast as {{dominant.youheshe}} come.",
  116. set_dominant:onTop|gotFucked,
  117. set_submissive:onBottom|didFuck,
  118. },
  119. {
  120. notags:force,
  121. tags:fInit,
  122. activity:"{{initiator.YouHeShe}} come to {{recipient.youName}} and spread legs. {{initiator.YouHeShe}} fuck like beast.",
  123. set_initiator:gotFucked,
  124. set_recipient:didFuck,
  125. },
  126. {
  127. tags:mf,
  128. notags:fSub,
  129. activity:"{{woman.YouName}} overwhelmed from lust. {{woman.YouHeShe}} spread legs for {{man.youhimher}} and get fucked.",
  130. set_woman:gotFucked,
  131. set_man:didFuck,
  132. },
  133. {
  134. tags:lp|reversal|mf,
  135. minD:40,
  136. activity:"{{follower.YouName}} tell {{leader.youName}} to get on ground so {{follower.youheshe}} can fuck on top. {{leader.YouName}} argue, saying {{leader.youheshe}} clan leader, but {{leader.youheshe}} timid and soon back down. Soon {{follower.youheshe}} fucking {{leader.youhimher}} from on top until {{leader.youheshe}} scream in climax.",
  137. dys:10,
  138. set_woman:gotFucked,
  139. set_follower:onTop,
  140. set_leader:didFuck,
  141. set_man:onBottom,
  142. },
  143. {
  144. notags:wrongO,
  145. tags:lp,
  146. activity:"{{leader.YouName}} tell {{follower.youhimher}} to lie on ground and spread legs. {{leader.YouHeShe}} want taste {{follower.yourhisher}} {{follower.manwoman}} parts. {{follower.YouName}} do as told and lie down while {{leader.youName}} lick and suck. It feel strange for {{follower.youName}} to have {{leader.yourNames}} mouth on privates, but soon {{follower.youheshe}} scream in pleasure.",
  147. set_leader:gaveOral,
  148. set_follower:gotOral,
  149. },
  150. {
  151. tags:reversal|mDom|lp|force,
  152. minD:40,
  153. minD:120,
  154. activity:"{{follower.YouName}} agree, but only if {{follower.youheshe}} on top. {{leader.YouName}} unsure at first, but back down and agree. {{follower.YouName}} ride up and down on {{leader.yourNames}} cock, surprised that it feel so good",
  155. dys:-4,
  156. leader:isMan,
  157. follower:isWoman,
  158. set_leader:didFuck|onBottom,
  159. set_follower:gotFucked|onTop,
  160. },
  161. {
  162. notags:rDom,
  163. tags:ff,
  164. activity:"{{initiator.YouName}} pull {{recipient.youName}} quietly behind tent. {{initiator.youheshe}} put hand on {{recipient.yourhisher}} thigh and gently slide up under clothes. Giving sly grin, {{initiator.youheshe}} slip fingers into {{recipient.yourNames}} wet pussy and begin rubbing. When {{recipient.youName}} start to make noise, {{initiator.youName}} silence with hard kiss until {{recipient.heshe}} scream climax into mouth.",
  165. set_initiator:gaveHandjob,
  166. set_recipient:gotHandjob,
  167. },
  168. {
  169. notags:fDom,
  170. tags:mDom,
  171. maxD:120,
  172. activity:"{{dominant.YouHeShe}} say for {{submissive.youName}} to get on ground, and {{submissive.youheshe}} {{eagerness}} obey. {{dominant.YouHeShe}} mount {{submissive.youhimher}} from behind and fuck {{submissive.yourhisher}} {{submissive.fuckhole}}.",
  173. dys:-5,
  174. set_dominant:didFuck|onTop,
  175. set_submissive:gotFucked|onBottom,
  176. },
  177. {
  178. notags:iDom,
  179. tags:mm,
  180. activity:"{{initiator.YouHeShe}} come to {{recipient.youName}} at night and in need. {{recipient.youName}} push {{initiator.himher}} on stomach and fuck manhole like pussy, releasing {{leader.yourhisher}} seed in it.",
  181. set_initiator:gotAnal|onBottom,
  182. set_recipient:gaveAnal|onTop,
  183. },
  184. {
  185. tags:mDom,
  186. activity:"{{dominant.YouHeShe}} throw {{submissive.youName}} to dirt and mount {{submissive.yourhisher}} {{submissive.fuckhole}}. {{dominant.YouHeShe}} fuck {{submissive.youName}} hard, making {{submissive.youName}} cry like shebeast in heat until {{submissive.youheshe}} cum. Soon {{dominant.YourHisHer}} seed erupt inside {{submissive.youhimher}}.",
  187. set_dominant:didFuck|onTop,
  188. set_submissive:gotFucked|onBottom,
  189. },
  190. {
  191. tags:fRec,
  192. maxD:40,
  193. activity:"{{initiator.YouName}} make {{recipient.youhimher}} scream with tongue and finger. Then {{initiator.youheshe}} lick {{recipient.youName}} like shecat till {{recipient.youName}} scream like beast.",
  194. set_initiator:gaveOral|gaveHandjob,
  195. set_recipient:gotOral|gotHandjob
  196. },
  197. {
  198. activity:"{{first.YouName}} fuck {{second.youName}} all night long.",//Got to have some baseline default.,
  199. set_first:didFuck|gotFucked,
  200. set_second:gotFucked|didFuck,
  201. },
  202. {
  203. notags:ff|reversal,
  204. tags:mDom,
  205. activity:"{{dominant.YouName}} motion to ground and command {{submissive.youhimher}} to get on knees. Because {{dominant.youheshe}} so dominant, {{submissive.youheshe}} quickly do what {{dominant.youheshe}} say. {{dominant.YouName}} take out man parts and motion for {{submissive.youhimher}} to suck, and soon {{submissive.youheshe}} take cock in mouth until {{dominant.youName}} baby juice fill mouth.",
  206. set_dominant:gotOral,
  207. set_submissive:gaveOral,
  208. },
  209. {
  210. notags:fDom,
  211. tags:mf,
  212. activity:"{{man.YouHeShe}} pull {{woman.youName}} to furs and push {{woman.yourhisher}} legs apart. Soon {{man.youheshe}} enter {{woman.youhimher}} and begin to fuck {{woman.yourhisher}} pussy.",
  213. set_man:didFuck|onTop,
  214. set_woman:gotFucked|onBottom,
  215. }
  216. ];
  217. /*
  218. * REACTIONS
  219. */
  220. sexReactions=[
  221. {
  222. tags:mf,
  223. activity:"Being on top make {{reactor.youName}} feel big and powerful, it only when {{other.yourhisher}} seed dribble down leg that {{reactor.youheshe}} realize {{reactor.youheshe}} still fucked as woman.",
  224. reactor:gotFucked|onTop|isSub,
  225. dys:3,
  226. },
  227. {
  228. notags:refused,
  229. minD:120,
  230. activity:"{{reactor.YourHisHer}} body betray {{reactor.youhimher}} by responding to {{other.yourhisher}} touch, making {{reactor.youhimher}} squirm and moan with pleasure.",
  231. reactor:gotFucked|isSub
  232. },
  233. {
  234. minD:80,
  235. activity:"{{reactor.YouHeShe}} still feel strange having this body and being fucked like womanfolk, but maybe {{reactor.youheshe}} start to like if it always feel this good.",
  236. reactor:isWoman|gotFucked,
  237. },
  238. {
  239. tags:lp,
  240. minD:120,
  241. activity:"{{reactor.YourHisHer}} body betray {{reactor.youhimher}} by responding to {{other.yourhisher}} touch, making you squirm and moan with pleasure as {{leader.heshe}} fuck you over and over until you filled with his seed",
  242. reactor:isSub|gotForced,
  243. dys:-5,
  244. },
  245. {
  246. activity:"{{reactor.YouName}} smile to self afterwards. {{other.name}} good with mouth.",
  247. reactor:gotOral,
  248. },
  249. {
  250. tags:lp,
  251. minD:140,
  252. activity:"It make {{reactor.youhimher}} feel very ashamed. {{reactor.YouHeShe}} not supposed to be like woman. Why this feel so good?",
  253. reactor:gotFucked|isSub,
  254. },
  255. {
  256. minD:90,
  257. activity:"{{reactor.YouName}} unhappily spit out fluids afterwards, and mutter to self. Can still taste {{other.yourNames}} {{other.manwoman}} parts in mouth for hours after.",
  258. reactor:gaveOral|gotForced
  259. },
  260. {
  261. minD:35,
  262. maxD:120,
  263. activity:"{{reactor.YouHeShe}} still {{reactor.hashave}} lingering taste of {{other.yourNames}} {{other.manwoman}} parts for hours after, but {{reactor.youName}} find that {{reactor.youheshe}} actually like it some.",
  264. reactor:gaveOral,
  265. },
  266. {
  267. maxD:45,
  268. activity:"{{reactor.YouHeShe}} coo happily to self afterwards. It feel good to be fucked by {{other.youName}}.",
  269. reactor:gotFucked|isSub
  270. },
  271. {
  272. maxD:35,
  273. activity:"{{reactor.YouName}} smile and thank {{other.youName}} for letting {{reactor.youhimher}} lick {{other.yourhisher}} {{other.genitals}}.",
  274. reactor:gaveOral,
  275. not_reactor:isDom,
  276. },
  277. {
  278. tags:lp,
  279. maxD:150,
  280. minD:20,
  281. activity:"It not feel right to get fucked like woman, but it also feel very good to obey strong leader commands.",
  282. reactor:gotFucked|isSub
  283. },
  284. {
  285. maxD:130,
  286. activity:"{{other.YourHisHer}} {{other.genitals}} taste good.",
  287. reactor:gaveOral
  288. },
  289. {
  290. tags:lp|force,
  291. minD:60,
  292. maxD:200,
  293. activity:"You still not happy to be used, but submitting to {{leader.name}} feel good.",
  294. reactor:gotFucked|isSub,
  295. },
  296. {
  297. minD:76,
  298. activity:"{{reactor.YouHeShe}} feel ashamed, but also maybe bit turned on too.",
  299. reactor:gotForced,
  300. },
  301. {
  302. activity:"{{reactor.YouHeShe}} pat {{other.youName}} on head and tell {{other.youhimher}} {{other.youheshe}} did good job.",
  303. not_reactor:isSub,
  304. reactor:gotOral,
  305. },
  306. {
  307. maxD:50,
  308. activity:"{{reactor.YouName}} smile and pat belly. {{reactor.YouHeShe}} happy to be bred by {{other.youName}}.",
  309. reactor:gotPiV,
  310. not_reactor:isPregnant
  311. },
  312. {
  313. maxD:50,
  314. activity:"It felt very good. {{reactor.YouHeShe}} cannot wait to do again.",
  315. },
  316. {
  317. tags:force,
  318. minD:20,
  319. maxD:140,
  320. activity:"Maybe it not so bad to be womanfolk.",
  321. reactor:gotFucked|isSub,
  322. }
  323. ];
  324. let setNotag = (x)=>(x.tags&refused==0)?x.notags|=refused:x;
  325. sexReactions.forEach(setNotag);
  326. sexActs.forEach(setNotag);
  327. compileEncounterOptions(sexActs);
  328. compileEncounterOptions(sexReactions);
  329. }
  330. //conversion from template string to handlebars:
  331. //%s/${\([^}]*}\)/{{\1}}/gc
  332. function initiateSex(initiator,target,forced){
  333. initiator.currentSexActs = 0;
  334. target.currentSexActs = 0;
  335. if(forced===undefined){
  336. forced=false;
  337. }
  338. var activity;
  339. var type = "other";
  340. var initiator = initiator;
  341. var recipient = target;
  342. var man;//only used when mixed sex couples
  343. var woman;
  344. if((target.isMale()||initiator.isMale())&&(target.isFemale()||initiator.isFemale())){
  345. if(target.isMale()){
  346. man=target;
  347. woman=initiator;
  348. }else{
  349. man=initiator;
  350. woman=target;
  351. }
  352. }
  353. var submissive;
  354. var dominant;
  355. if((initiator==leader)||(target==leader)||(Math.abs(target.submissiveness-initiator.submissiveness)>40)){
  356. if((initiator==leader)||((target.submissiveness-initiator.submissiveness)>40)){
  357. dominant=initiator;
  358. submissive=target;
  359. }else{
  360. dominant=target;
  361. submissive=initiator;
  362. }
  363. }
  364. var first;//scenes that can work either way and we want to randomize a bit
  365. var second;
  366. if(Math.random()>0.5){
  367. first=initiator;
  368. second=target;
  369. }else{
  370. first=target;
  371. second=initiator;
  372. }
  373. var notsub;//if a role can be either normal or dom/sub, but should never be done by the sub in a scene.
  374. var notdom;
  375. if(dominant){
  376. notsub = dominant;
  377. notdom = submissive;
  378. }else{//if there is no dom and sub, the order does not matter. can be either
  379. notsub=first;
  380. notdom=second;
  381. }
  382. var follower;
  383. var playerHere = (initiator===player)||(target===player);
  384. var leaderHere = (initiator===leader)||(target===leader);
  385. if(leaderHere){
  386. if(initiator===leader){
  387. follower=target;
  388. }else{
  389. follower=initiator;
  390. }
  391. }
  392. var genitalReact = (chr=>chr.isMale()?"cock swell":"pussy ache");
  393. var playerFucked = true;
  394. var leaderFucked = false;//if female leaderg fucked by male player.
  395. /*These are set here for convenience in definitions*/
  396. const iDom = SexEncounterFlags.iDom;
  397. const rDom = SexEncounterFlags.rDom;
  398. const mf = SexEncounterFlags.mf;
  399. const mm = SexEncounterFlags.mm;
  400. const ff = SexEncounterFlags.ff;
  401. const futa = SexEncounterFlags.futa;
  402. const iHot = SexEncounterFlags.iHot;
  403. const iUg = SexEncounterFlags.iUg;
  404. const refused = SexEncounterFlags.refused;//successfully refused to fuck
  405. const force = SexEncounterFlags.force;//encounter was forced (generally by leader). Maybe
  406. const wrongO = SexEncounterFlags.wrongO;//target has wrong orientation for initiator
  407. const lp = SexEncounterFlags.lp;//leader/player interaction
  408. const reversal = SexEncounterFlags.reversal;//submissiveness stat is different from leader/follower dynamic
  409. const mDom = SexEncounterFlags.mDom;//male dominant
  410. const fDom = SexEncounterFlags.fDom;//female dominant
  411. const fSub = SexEncounterFlags.fSub;
  412. const mSub = SexEncounterFlags.mSub;
  413. const fRec = SexEncounterFlags.fRec;//female recipient
  414. const mRec = SexEncounterFlags.mRec;
  415. const mInit = SexEncounterFlags.mInit;//initiator is male
  416. const fInit = SexEncounterFlags.fInit;
  417. /*
  418. *Character Flags
  419. */
  420. const gotPiV = SexFlags.gotPiV;
  421. const gavePiV = SexFlags.gavePiV;
  422. const gaveOral=SexFlags.gaveOral;
  423. const gotOral =SexFlags.gotOral;
  424. const gotAnal =SexFlags.gotAnal;
  425. const gaveAnal =SexFlags.gaveAnal;
  426. const gotFucked=SexFlags.gotFucked;//"generic" fucking that changes depending on participant genders
  427. const didFuck=SexFlags.didFuck; //will also set the relevant flags between sex and reflection steps.
  428. const gaveHandjob=SexFlags.gaveHandjob;
  429. const gotHandjob=SexFlags.gotHandjob;
  430. const onTop=SexFlags.onTop;
  431. const onBottom=SexFlags.onBottom;
  432. const isSub=SexFlags.isSub;
  433. const isDom=SexFlags.isDom;
  434. const gotForced=SexFlags.gotForced;
  435. const didForce=SexFlags.didForce;
  436. const isMan = SexFlags.isMan;
  437. const isWoman = SexFlags.isWoman;
  438. const isFuta = SexFlags.isFuta;
  439. const didSuckCock =SexFlags.didSuckCock;
  440. const gotCockSucked = SexFlags.gotCockSucked;
  441. const didLickPussy = SexFlags.didLickPussy;
  442. const gotPussyLicked=SexFlags.gotPussyLicked;
  443. const isPregnant = SexFlags.isPregnant;
  444. /*Flag Checks*/
  445. var isIDom = (dominant&&(dominant==initiator))?iDom:0;
  446. var isRDom = (dominant&&(dominant==target))?rDom:0;
  447. var isMF = ((man!==undefined)&&(woman!==undefined))?mf:0;
  448. var isMM = target.isMale()&&initiator.isMale()?mm:0;
  449. var isFF = target.isFemale()&&initiator.isFemale()?ff:0;
  450. var isFutaEncounter = target.isFutanari()||initiator.isFutanari()?futa:0;
  451. var isIHot = ((target.orientation<30)&&(initiator.femininity()>80))||((target.orientation>70)&&(initiator.masculinity()>80))?iHot:0;
  452. var isIUg = ((target.orientation<30)&&(initiator.masculinity()>60))||((target.orientation>70)&&(initiator.femininity()>60))?iUg:0;
  453. var isForced = forced?force:0;
  454. var isLP = (leaderHere&&playerHere)?lp:0;
  455. var isReversal = (dominant&&((dominant.submissiveness-submissive.submissiveness)>20))?reversal:0;//leader is always the "dominant" if available, but submissiveness can potentially be reversed
  456. if(isReversal){//but go ahead and swap so generic dom/sub can be used
  457. let tmp = dominant;
  458. dominant=submissive;
  459. submissive=tmp;
  460. }
  461. var isWrongO = (((initiator.orientation<35)&&(target.hasCock() || target.isMale()))||
  462. ((initiator.orientation>65)&&(target.hasVagina() || target.isFemale()))) ? wrongO:0;
  463. /*console.log("reversal",isReversal,dominant.submissiveness,submissive.submissiveness);
  464. console.log(dominant.name,submissive.name);*/
  465. var isMDom = dominant&&dominant.isMale()?mDom:0;
  466. var isFDom = dominant&&dominant.isFemale()?fDom:0;
  467. var isFSub = submissive&&submissive.isFemale()?fSub:0;
  468. var isMSub = submissive&&submissive.isMale()?mSub:0;
  469. var isFRec = recipient&&recipient.isFemale()?fRec:0;
  470. var isMRec = recipient&&recipient.isMale()?mRec:0;
  471. var isFInit = initiator&&initiator.isFemale()?fInit:0;
  472. var isMInit = initiator&&initiator.isMale()?mInit:0;
  473. var tagmask = isIDom|isRDom|isMF|isMM|isFF|isFutaEncounter|isIHot|isIUg|isForced|isLP|isReversal|isWrongO|isMDom|isFDom|isFSub|isMSub|isFRec|isMRec|isMInit|isFInit;
  474. var argue;
  475. var react;
  476. var act;
  477. var dys = player.dysphoria;
  478. var characters = {
  479. player:player,
  480. leader:leader,
  481. follower:follower,
  482. initiator:initiator,
  483. recipient:recipient,
  484. target:target,
  485. man:man,
  486. woman:woman,
  487. submissive:submissive,
  488. dominant:dominant,
  489. notsub:notsub,
  490. notdom:notdom,
  491. first:first,
  492. second:second,
  493. }
  494. if(dominant){
  495. dominant.currentSexActs |= isDom;
  496. }
  497. if(submissive){
  498. submissive.currentSexActs |= isSub;
  499. }
  500. function setSexMask(chr){
  501. chr.currentSexActs |= chr.isMale()?isMan:0;
  502. chr.currentSexActs |= chr.isFemale()?isWoman:0;
  503. chr.currentSexActs |= chr.isFutanari()?isFuta:0;
  504. chr.currentSexActs |= chr.isPregnant()?isPregnant:0;
  505. }
  506. setSexMask(initiator);
  507. setSexMask(target);
  508. /*Initialize unused people.
  509. Templates will error otherwise.
  510. in theory these shouldn't get used ever if created here like initiator
  511. aside from templates
  512. could maybe get better solution if we used some other form of templating that explicitly resolved later*/
  513. if(!submissive){submissive=leader;}
  514. if(!dominant){dominant=second;}
  515. if(!follower){follower=second;}
  516. if(!woman){woman=first;}
  517. if(!man){man=second;}
  518. var eagerness = "quickly";
  519. if(isIHot){
  520. eagerness="eagerly";
  521. }
  522. if(isIUg){
  523. eagerness="reluctantly";
  524. }
  525. if(forced){
  526. let reluctance = target.dysphoria;
  527. if(isIHot){
  528. reluctance-=50;
  529. }
  530. if(isIUg){
  531. reluctance+=50;
  532. }
  533. if(reluctance>170){
  534. eagerness="angrily";
  535. }else if(reluctance>100){
  536. eagerness="grudgingly";
  537. }else if(reluctance<50){
  538. eagerness="quickly";
  539. }else if(reluctance<20){
  540. eagerness="eagerly";
  541. }
  542. }
  543. var argues = [
  544. {
  545. tags:rDom|force,
  546. minD:150,
  547. set:refused,
  548. activity: "{{target.YouHeShe}} shout at {{initiator.youName}}, yelling that {target.youheshe} not {{initiator.yourshishers}} to use",
  549. },
  550. {
  551. tags:iUg|force,
  552. notags:iDom,
  553. minD:40,
  554. set:refused,
  555. activity:"{{initiator.YouHeShe}} so hideous that {{target.youheshe}} refuse to fuck {{initiator.youhimher}}",
  556. },
  557. {
  558. tags:iHot|force,
  559. minD:75,
  560. activity:"{{target.YouHeShe}} think about refusing, but {{initiator.heshe}} so hot it make {{target.yourhisher}} {{target,arousedReaction}}.",
  561. },
  562. {
  563. tags:force|fSub,
  564. minD:120,
  565. activity:"{{target.YouHeShe}} argue, saying {{target.youheshe}} not woman, but {{initiator.heshe}} point and say {target.yourhisher} body is woman body, so {{target.youheshe}} fuck like woman.",
  566. },
  567. {
  568. notags:force,
  569. tags:iUg,
  570. set:refused,
  571. minD:40,
  572. activity:"{{target.YouName}} curl lips in disgust, saying {{target.youheshe}} never fuck {{initiator.youName}}."
  573. }
  574. ];
  575. function setActMasks(character,others){
  576. var other;
  577. for(let o in others){
  578. if(others[o]!==character){
  579. other=others[o];
  580. }
  581. }
  582. var setGeneric=true;
  583. var mask= character.currentSexActs;
  584. const othermask = other.currentSexActs;
  585. if(mask & (gaveAnal|gavePiV)){
  586. setGeneric=false;
  587. mask|=gotFucked;
  588. }
  589. if(mask & (gaveAnal|gavePiV)){
  590. setGeneric=false;
  591. mask|=didFuck;
  592. }
  593. if(mask& (didLickPussy|didSuckCock)){
  594. setGeneric=false;
  595. mask|=gaveOral;
  596. }
  597. if(mask & (gotCockSucked|gotPussyLicked)){
  598. setGeneric=false;
  599. mask |= gotOral;
  600. }
  601. if(setGeneric){
  602. if(mask&gotFucked){
  603. if(tagmask&mf){
  604. mask|=gotPiV;
  605. }
  606. if(tagmask&mm){
  607. mask|=gotAnal;
  608. }//what, if anything, should ff produce?
  609. }
  610. if(mask&didFuck){
  611. if(tagmask&mf){
  612. mask|=gavePiV;
  613. }
  614. if(tagmask&mm){
  615. mask|=gaveAnal;
  616. }
  617. }
  618. if(mask&gaveOral){
  619. if(othermask&isWoman){
  620. mask|=didLickPussy;
  621. }
  622. if(othermask&isMan){
  623. mask|=didSuckCock;
  624. }
  625. if(othermask&isFuta){
  626. mask|=didSuckCock;//Will also get pussy licked from above. Is that correct?
  627. }
  628. }
  629. if(mask&gotOral){
  630. if(mask&isFuta){
  631. mask|=gotCockSucked;
  632. }
  633. if(mask&isMan){
  634. mask|=gotCockSucked;
  635. }
  636. if(mask&isWoman){
  637. mask|=gotPussyLicked;
  638. }
  639. }
  640. }
  641. if((tagmask&force) && (!(tagmask&(refused|reversal)))){
  642. if(mask&isSub){
  643. mask|=gotForced;
  644. }else if(mask&isDom){
  645. mask|=didForce;
  646. }else if(mask&(gotPiV|gotFucked|gotAnal)){
  647. mask|=gotForced;
  648. }else if(mask&(gavePiV|didFuck|gaveAnal)){
  649. mask|=didForce;
  650. }
  651. }
  652. character.currentSexActs=mask;
  653. //console.log(mask);
  654. }
  655. //var argueScore = getRandomInt(4,8) - 1*(player.dysphoria>15)-1*(player.dysphoria>60)-1*(player.dysphoria>100)-1*(player.dysphora>160);
  656. //if(argueScore<4){/*/*
  657. /*if(!forced){
  658. argue = handleResult(getRandomElem(argues.filter(checkChoice)));
  659. }else{
  660. argue="";
  661. }*/
  662. //}
  663. //act = handleResult(getRandomElem(acts.filter(checkChoice,follower)));
  664. //console.log("initiator",initiator.name,"recipient",recipient.name);
  665. var uniqueCharacters = {initiator:initiator,target:target};
  666. var useDys = function(characters,tags){
  667. if((tags&lp)){
  668. return follower;
  669. }else{
  670. return false;
  671. }
  672. }
  673. var activities = generateEncounter(tagmask,[
  674. {
  675. name:"act",
  676. possibilities:sexActs,
  677. characters:characters,
  678. uniqueCharacters:uniqueCharacters,
  679. characterTags:"currentSexActs",
  680. handleTags:setActMasks,
  681. useDysphoria:useDys,
  682. },
  683. {
  684. name:"initiatorReaction",
  685. possibilities:sexReactions,
  686. characters:{reactor:initiator,other:target,...characters},
  687. uniqueCharacters:uniqueCharacters,
  688. characterTags:"currentSexActs",
  689. useDysphoria:useDys,
  690. },
  691. {
  692. name:"targetReaction",
  693. possibilities:sexReactions,
  694. characters:{reactor:target,other:initiator,...characters},
  695. uniqueCharacters:uniqueCharacters,
  696. characterTags:"currentSexActs",
  697. useDysphoria:useDys,
  698. }],["{{act}} {{initiatorReaction}}","{{act}} {{targetReaction}}"]);
  699. /*initiatorReact = handleResult(getReaction(initiator,recipient),true);
  700. recipientReact = handleResult(getReaction(recipient,initiator),true);
  701. var initiatorActivity = argue+" "+act;
  702. var recipientActivity = argue+" "+act;
  703. if(initiatorReact!==undefined){
  704. initiatorActivity+= " "+initiatorReact;
  705. }
  706. if(recipientReact!==undefined){
  707. recipientActivity+=" "+recipientReact;
  708. }*/
  709. if(initiator.currentSexActs&(gotFucked|didFuck|gotOral)){
  710. initiator.desire=0;
  711. if(initiator.currentSexActs&gotPiV){
  712. initiator.maybeImpregnate(target);
  713. }
  714. }
  715. if(target.currentSexActs&(gotFucked|didFuck|gotOral)){
  716. target.desire=0;
  717. if(target.currentSexActs&gotPiV){
  718. target.maybeImpregnate(initiator);
  719. }
  720. }
  721. /* Maybe later
  722. if((tagmask&fuckLtP)==fuckLtP){
  723. eatStatNut(player,getRandomElem(["allure","maternalism","orientation"]),getRandomInt(3,7));
  724. avatar.activity+=activity;
  725. //player.activity+=activity;
  726. //player.dysphoria-=5;
  727. if((tagmask&(mL|fP))==(mL|fP)){
  728. player.maybeImpregnate(avatar);
  729. }
  730. }
  731. if((tagmask&fuckPtL)==fuckPtL){
  732. eatStatNut(player,getRandomElem(["allure","maternalism","orientation"]),getRandomInt(-3,-1));
  733. eatStatNut(avatar,getRandomElem(["allure","orientation","submissiveness"]),getRandomInt(2,4));
  734. //avatar.activity+=activity;
  735. //player.activity+=activity;
  736. if((tagmask&(mP|fL))==(mP|fL)){
  737. avatar.maybeImpregnate(player);
  738. }
  739. }*/
  740. return activities;
  741. }