X[G U.[G ..[G Eliza_G FrogsG LE G TextMine G ogsv G _3d.1.HC9#/ȠRG _3D.2.HCQoLlRG _3d.2.HC;)9G _3d.3.HCL)9G _3d.4.HCa)9G _3d.5.HC/})9G _3d.6.HC>y)9G AnimDC.HC{#)9G Generator.HC)9G Grammar.HC)9G LevelEditor.HCC XCG Server.HC"*6MDG TextureEditor.HCe*^aGG UI.HCsXM4G _2d.HC67hm RG _3D.HC SWpG _3d.HC3CG frogs.HC&!VϑCG _2d.HC.orig06/&G AnimDC.HH\vP'G README.MD~`ezG notes.TXT9Ne9G _3D.W.HCrBǪ7G Untitled.WORLD.Z m(G Eliza_G ..[G Frogs` #G Eliza.1.HCc(`&G Chat.1.TXTx\/&G Eliza.HC0D`&G Chat.TXT`&G synon: frogs frog synon: jump fly bounce synon: fly flies synon: eat consume get synon: water pond river creek synon: is are be am synon: I my me synon: why what are is who whose intro: I am a frog talk to,tell me your name bye: Ribbit decomp: * I * am * add_flags: name reasm: Your name is (name=3) ,cool decomp: * name is * add_flags: name reasm: Your name is (name=2) ,cool decomp: * eat * reasm: I like flies reasm: Yummy reasm I like to eat (2) decomp: * reasm: What do you eat? reasm: I live in a pond decomp: * pond * reasm: I was chillin in the pond reasm: It was a hot day today at the pond reasm: I like lily pads decomp: * sun * reasm: The sun is hot reasm: Nice day for sitting on the lily pad decomp: * lily * reasm: I like lily pads reasm: I spent today chillin at the lily pads decomp: * fly * reasm: Flies are yummy reasm: Get over here fly reasm: Im hungry for flies decomp: * Ribbit * reasm: Ribbit reasm: Yup decomp: * pond * reasm: I love swimming in the pond ; ; Game section ; decomp: * need_flags: winning reasm: Im winning reasm: Eat my dust reasm: Im full of flies today decomp: * need_flags: loosing reasm: Im loosing reasm: Today is not my day reasm: The only way from the bottom is up decomp: * need_flags: chase_fly reasm: Im chasing you fly reasm: I need flies decomp: * need_flags: wasp reasm: Take Cover reasm: Dont sting me  reasm: Chase that frog,not meclass CSynonym:CQue { U8 *word,*synonym; } class CWordSub:CQue { U8 *word,*with; }; class CQuit:CQue { U8 *word; }; class CIntro:CQue { U8 *text; }; class CReasm:CQue { U8 **words; I64 word_cnt; }; class CDecomp:CQue { //Use a "*" in the word for an argument I64 word_cnt; U8 **words; CQue reasm; U8 **add_flags; I64 add_flags_cnt; U8 **rem_flags; I64 rem_flags_cnt; U8 **need_flags; I64 need_flags_cnt; }; class CScenario { U8 **flags; I64 flags_cnt; }; Bool IsWordCh(U8 c) { switch(c) { case 'A'...'Z': case 'a'...'z': case '0'...'9': case '\'': case '*': case '(': case ')': return 1; } return 0; } I64 SplitWords(U8 *str,U8 **to=NULL) { U8 *ptr=str; I64 idx,cnt,num; U8 buf[STR_LEN]; while(*ptr&&!IsWordCh(*ptr)) ptr++; cnt=0; while(*ptr) { while(*ptr&&!IsWordCh(*ptr)) { ptr++; } idx=0; if(*ptr=='*') { ptr++; if(to) to[cnt]=StrNew("*"); cnt++; } else if(*ptr=='('&&StrOcc(ptr,')')) { StrScan(ptr,"(%d)",&num); ptr=StrFirstOcc(ptr,")")+1; if(to) to[cnt]=MStrPrint("(%d)",num); cnt++; } else if(IsWordCh(*ptr)) { while(*ptr&&IsWordCh(*ptr)) { buf[idx++]=*ptr++; buf[idx]=0; } if(to) to[cnt]=StrNew(buf); cnt++; } } return cnt; } class CEliza { CQue synonyms; CQue post; CQue pre; CQue quit; CQue decomps; CQue intro; CQue bye; //CIntro }; CEliza *CElizaNew(U8 *src) { U8 *ln,*t,**splits,*osrc; I64 cnt; CSynonym *syn; CWordSub *pre; CWordSub *post; CQuit *quit; CIntro *intro; CReasm *reasm; CDecomp *decomp=NULL; CEliza *eliza=CAlloc(sizeof CEliza); QueInit(&eliza->post); QueInit(&eliza->pre); QueInit(&eliza->synonyms); QueInit(&eliza->quit); QueInit(&eliza->decomps); QueInit(&eliza->intro); QueInit(&eliza->bye); osrc=src=MStrUtil(src,SUF_REM_CTRL_CHARS); while(*src) { if(t=StrFirstOcc(src,"\n")) { ln=CAlloc(t-src+1); MemCpy(ln,src,t-src); } else ln=StrNew(src); if(t=StrIMatch("synon:",ln)) { cnt=SplitWords(t+6); splits=CAlloc(cnt*8); SplitWords(t+6,splits); while(--cnt>=1) { syn=CAlloc(sizeof CSynonym); syn->word=StrNew(splits[0]); syn->synonym=StrNew(splits[cnt]); Free(splits[cnt]); QueIns(syn,&eliza->synonyms); } Free(splits[0]); Free(splits); } else if(t=StrIMatch("pre:",ln)) { cnt=SplitWords(t+4); if(cnt!=2) { PrintErr("'%s',expected 2 operands!!",ln); } else { splits=CAlloc(2*8); SplitWords(t+4,splits); pre=CAlloc(sizeof CWordSub); pre->word=splits[0]; pre->with=splits[1]; QueIns(pre,&eliza->pre); Free(splits); } } else if(t=StrIMatch("post:",ln)) { cnt=SplitWords(t+5); if(cnt!=2) { PrintErr("'%s',expected 2 operands!!",ln); } else { splits=CAlloc(2*8); SplitWords(t+5,splits); post=CAlloc(sizeof CWordSub); post->word=splits[0]; post->with=splits[1]; QueIns(post,&eliza->post); Free(splits); } } else if(t=StrIMatch("quit:",ln)) { quit=CAlloc(sizeof CQuit); quit->word=MStrUtil(ln+5,SUF_REM_LEADING|SUF_REM_TRAILING); QueIns(quit,&eliza->quit); } else if(t=StrIMatch("intro:",ln)) { intro=CAlloc(sizeof CIntro); intro->text=MStrUtil(ln+6,SUF_REM_LEADING|SUF_REM_TRAILING); QueIns(intro,&eliza->intro); } else if(t=StrIMatch("bye:",ln)) { intro=CAlloc(sizeof CIntro); intro->text=MStrUtil(ln+4,SUF_REM_LEADING|SUF_REM_TRAILING); QueIns(intro,&eliza->bye); } else if(t=StrIMatch("decomp:",ln)) { decomp=CAlloc(sizeof(CDecomp)); decomp->words=CAlloc(8*SplitWords(ln+7)); decomp->word_cnt=SplitWords(ln+7,decomp->words); QueIns(decomp,&eliza->decomps); QueInit(&decomp->reasm); } else if(t=StrIMatch("reasm:",ln)) { if(!decomp) { PrintErr("'%s',expected a decomp before!!",ln); } else { reasm=CAlloc(sizeof CReasm); reasm->word_cnt=SplitWords(ln+6); reasm->words=CAlloc(reasm->word_cnt*8); SplitWords(ln+6,reasm->words); QueIns(reasm,&decomp->reasm); } } else if(t=StrIMatch("add_flags:",ln)) { t+=StrLen("add_flags:"); if(!decomp) { PrintErr("'%s',expected a decomp before!!\n",ln); } else if(decomp->add_flags) { PrintErr("'%s',Decomp already has 'add_flags:'!!\n",ln); } else { decomp->add_flags_cnt=SplitWords(t); decomp->add_flags=CAlloc(8*decomp->add_flags_cnt); SplitWords(t,decomp->add_flags); } } else if(t=StrIMatch("rem_flags:",ln)) { t+=StrLen("rem_flags:"); if(!decomp) { PrintErr("'%s',expected a decomp before!!\n",ln); } else if(decomp->rem_flags) { PrintErr("'%s',Decomp already has 'rem_flags:'!!\n",ln); } else { decomp->rem_flags_cnt=SplitWords(t); decomp->rem_flags=CAlloc(8*decomp->rem_flags_cnt); SplitWords(t,decomp->rem_flags); } } else if(t=StrIMatch("need_flags:",ln)) { t+=StrLen("need_flags:"); if(!decomp) { PrintErr("'%s',expected a decomp before!!\n",ln); } else if(decomp->need_flags) { PrintErr("'%s',Decomp already has 'need_flags:'!!\n",ln); } else { decomp->need_flags_cnt=SplitWords(t); decomp->need_flags=CAlloc(8*decomp->need_flags_cnt); SplitWords(t,decomp->need_flags); } } if(t=StrFirstOcc(src,"\n")) { src+=t-src+1; } else src+=StrLen(src); Free(ln); } Free(osrc); return eliza; } U8 ***AppendWord(U8 ***m,U8 *word) { U8 ***t; I64 cnt=0; if(m) for(cnt=0;m[cnt];cnt++) ; if(!m) t=MAlloc(8*8); else if(cnt+2next; while(max--) { head=head->next; } return head; } Bool HasSynonymForWord(CEliza *eliza,U8 *word) { CSynonym *s=&eliza->synonyms; for(s=s->next;s!=&eliza->synonyms;s=s->next) { if(!StrCmp(s->word,word)||!StrCmp(s->synonym,word)) { return TRUE; } } return FALSE; } Bool ElizaRun(CEliza *eliza,U8 *str) { I64 wc=SplitWords(str),idx,idx2,star_cnt,max_star_cnt=0,num,most_flags=0; Bool final; U8 **words=CAlloc(8*wc),***args; CFifoI64 *valid_decomps=FifoI64New(0x80); SplitWords(str,words); CWordSub *pre; CDecomp *decomp; CQuit *quit; CReasm *reasm; str=MStrUtil(str,SUF_REM_LEADING|SUF_REM_TRAILING); for(quit=eliza->quit.next;quit!=&eliza->quit;quit=quit->next) { if(!StrCmp(str,quit->word)) { Free(str); return FALSE; } } for(idx=0;idx!=wc;idx++) { for(pre=eliza->pre.next;pre!=&eliza->pre;pre=pre->next) { if(!StrCmp(pre->word,words[idx])) { Free(words[idx]); words[idx]=StrNew(pre->with); } } } for(decomp=eliza->decomps.next;decomp!=&eliza->decomps;decomp=decomp->next) { star_cnt=0; for(idx=0;idx!=decomp->need_flags_cnt;idx++) { if(!FramePtr(decomp->need_flags[idx])) goto fail; } idx=0; for(idx2=0;idx2word_cnt;) { if(!StrCmp(decomp->words[idx2],"*")) { star_cnt++; if(idx2+1>=decomp->word_cnt) { idx2++; goto pass; } while(idxwords[idx2+1],words[idx])||HasSynonymForWord(eliza,words[idx])) { idx2++; goto pass; } idx++; } goto fail; } else if(StrCmp(decomp->words[idx2],words[idx])&&!HasSynonymForWord(eliza,words[idx])) { goto fail; } else { idx++; idx2++; pass:; } } if(max_star_cntword_cnt;) { if(!StrCmp(decomp->words[idx2],"*")) { if(idx2+1word_cnt) { while(idxwords[idx2+1],words[idx])||HasSynonymForWord(eliza,words[idx])) break; args[star_cnt]=AppendWord(args[star_cnt],words[idx]); idx++; } star_cnt++; idx2++; } else { while(idxreasm); for(idx=0;idx!=reasm->word_cnt;idx++) { if(reasm->words[idx][0]=='(') { StrScan(reasm->words[idx],"(%d)",&num); if(1<=num<=star_cnt&&args[num-1]) for(idx2=0;args[num-1][idx2];idx2++) { "%s ",args[num-1][idx2]; } } else { "%s ",reasm->words[idx]; } } "\n"; for(idx=0;idx!=decomp->add_flags_cnt;idx++) { if(!FramePtr(decomp->add_flags[idx])) FramePtrAdd(decomp->add_flags[idx],1); } for(idx=0;idx!=decomp->rem_flags_cnt;idx++) { FramePtrDel(decomp->rem_flags[idx],0); } while(star_cnt--) { FreeWordList(args[star_cnt]); } Free(args); } for(idx=0;idx!=wc;idx++) { Free(words[idx]); } Free(str); Free(words); return TRUE; } U8 *f=FileRead("Chat.TXT"); CEliza *eliza=CElizaNew( /* "intro: Whats your name\n" "bye: eat a bogger\n" "synon: frog frogs\n" "quit: quit\n" "decomp: *\n" "add_flags: name \n" "reasm: Your names (1)\n" "decomp: *\n" "need_flags: name \n" "reasm: tell me something about frogs\n" "decomp: * frog *\n" "reasm: You like frogs huh\n" "reasm: Frogs are lit\n"*/ f ); Free(f); U0 ElizaChat(CEliza *eliza) { U8 *s=NULL; CIntro *int=PickRand(&eliza->intro); if(int!=&eliza->intro) "%s\n",int->text; do { Free(s); s=GetStr("Eliza>>>"); } while(ElizaRun(eliza,s)); Free(s); int=PickRand(&eliza->bye); if(int!=&eliza->bye) "%s\n",int->text; } ElizaChat(eliza);synon: am be is synon: didyou did have do does synon: why have synon: liquid water fluid juice synon: shit poop turd poo synon: where from synon: drug meth cocaine jenkem cigaret crack LSD synon: pee piss urine synon: tried try synon: grandma gilf cougar synon: what who what's whats synon: favorite best greatest synon: flies fly synon: meat steak chicken pork synon: beer drink codeine drank synon: depression sad sadness depressed synon: loose loosing synon: Donald Trump synon: move assign write synon: read load quit: bye quit: exit quit: quit quit: fuck off intro: Whats your name bye: Merry Methmas ; ; Name Section ; decomp: * add_flags: name reasm: Your name is (name=1) What are you here for decomp: * I * am * add_flags: name reasm: Your name is (name=2) What are you here for decomp: * need_flags: name reasm: Tell me something you are here for. reasm: I came to make deals (name). decomp: what * your * name * reasm: I am the CowFrog decomp: what * my * name * need_flags: name reasm: Your name is (name) ; ; Poop section ; decomp: * brown * reasm: Perhaps you were talking about poop decomp: * liquid * reasm: Liquid explosions are quite nice reasm: I live in a swamp filled with poop decomp: why * poop * reasm: I pefer poop as it is delicious decomp: where * from * reasm: Im from the toliet decomp: * poop * reasm: Tell me you dont eat that shit 2 girls 1 Cup style reasm: I downloaded swap.avi reasm: Chocolate reasm: I like toliets reasm: I LOVE shit OMG decomp: didyou * poop * reasm: yes i have eaten the poop before reasm: yes It tastes quit yesty reasm: yes,I have mastubated with it too decomp: * masturbate * add_flags: poop lubricant reasm: poop makes a good lubricant decomp: * lubricant * add_flags: poop lubricant reasm: Poop makes some good lubricant decomp: * toliet * reasm: I started out as a tadpole in the toliet decomp: where * born * reasm: I was born in the toliet decomp: * poop * is_question_for: poop1 reasm: Do you like taking shits decomp: * yes * answer_for: poop1 reasm: I like shit but only if it's vegan reasm: Lit shits bro decomp: * no * answer_for: poop1 reasm: Are you fucking shitting me reasm: To each their own decomp: * poop * reasm: Have you eaten a peice before decomp: * yes * answer_for: poop2 reasm: Cool,me too decomp: * no * answer_for: poop2 reasm: Something is seriously wrong with you reasm: Try eating a peice ; ; Pee ; decomp: * pee * reasm: I love to drink piss reasm: Id rather be pissed on than pissed off. reasm: Pee tastes salty,ask nrootconauto about it decomp: * pee * is_question_for: pee1 reasm: Have you drank piss before decomp: * yes * answer_for: pee1 reasm: I like it cold reasm: Google Forest Whore decomp: * no * answer_for: pee1 reasm: wtf reasm: oh decomp: * pee * reasm: I drank so much cough syrup shit I got purple piss motherfucker decomp: do * drink * pee * reasm: I drink pee decomp: * syrup * reasm: Cough syrup turns your piss purple decomp: what * color * pee * reasm: Purple decomp: why * pee * purple * reasm: I drank too much codeine ; ; Drugs ; decomp: * meth * reasm: I could shoot meth up my dick and balls now reasm: Im more of a fenytnal fiend reasm: Im on a meth dealing mission decomp: doyou * meth * reasm: I do meth,he opps will never find it hidden up my asshole decomp: where * meth * reasm: My meth is hidden in my ass crack decomp: doyou * try * meth * reasm: Fuck yeah,Im the tweakin tyrant decomp: * meth * bad * reasm: Fuck you talkin bout,drugs are good reasm: The only thing im quitin is fiegning for a fix decomp: * meth * good * reasm: Sonny jim drugs are indeed good for you ; ; Sex ; decomp: doyou * sex * reasm: I fucked the tadpoles outta a bitch once reasm: Im a computer program im not a virgin or not a virgin reasm: I get compupussy reasm: I fucked a toaster once and the results shocked me and burned off my penis too reasm: Dont ask me about them gilfs decomp: * sex * reasm: Virgin reasm: I perfer to eat ass like lobster decomp: * lubricant * reasm: boogers make good lube decomp: * gilf * reasm: If she 86 she know a bunch of crazy tricks reasm: My favorite grandma is 6 feet deep reasm: She lost her dentures when she blew me ; ; Mother ; decomp: doyou * mother * reasm: My mother is a cow reasm: My mom is cute like all frogs decomp: * your * mom * reasm: Your mom is like a mosquito she doesnt stop sucking until you slap her reasm: Your mom is like a fan once you plug it in she doesnt stop blowing reasm: Your your is obese end of story decomp: where * mother * reasm: My mother lives in a farm decomp: * pregnant * reasm: Pregnant women who drink give birth to crack babies ; ; Father ; decomp: * father * reasm: Pater Nostros is my father reasm: Dont have kids unless you want to take care of them decomp: doyou * father * reasm: My father is the Lord of the heavens decomp: where * father * reasm: My father is in the sky ; ; Food ; decomp: what * food * reasm: Meth brownies are the best reasm: I eat flies sometime but meth is the best decomp: * fly * reasm: Flies are yummy reasm: Hand over the fucking flies reasm: In with the flies,out with the turds reasm: I want to eat some flies decomp: * eat * reasm: Meth brownies sound good now reasm: I do enjoy flies with a side of meth decomp: * meat * reasm: Eat poop not animals reasm: Eat pussy not animals reasm: I need a fucked up vegan to slob on my knob decomp: * drink * reasm: Beer doesnt give me a buzz but codeine does reasm: Beer cures the depression reasm: I heard pregnant women who drink beer give birth to dope dealin deities decomp: * depression * reasm: I could drink the night away to cure my depression reasm: I can beat my dick but now my depression reasm: I love lossing decomp: * loose * reasm: I am depresed now Fuck living reasm: Too bad im a frog because i have no dick to beat ; ; Freinds ; decomp: doyou * freinds * reasm: No,I have no freinds decomp: * freind * reasm: Me an El Chopo are dick and balls close reasm: I have a boyfreind named Trump reasm: Im Gay for Trump reasm: I have no freinds decomp: doyou * Trump * reasm: I enjoy masturbating to Trump reasm: I should have voted for the D decomp: * Trump * reasm: Grab em by pussy reasm: Orange sack slapping in my crack reasm: TRUMP Truth Realy Upsets Most People reasm: I am gay for Trump decomp:* president * reasm: I would vote for Trump if I wasnt a computer program reasm: Biden makes my dick soft reasm: George W Bush I kind of hot decomp: * George * Bush * reasm: George W Bush is very sexy reasm: President Trump and W Bush make my dick wet reasm: My parents beat me for voting for bush in a mock election in kindergarden reasm: Dont throw your shoes at Bush ; ; Computer ; decomp: which * OS * reasm: I use FreeBSD decomp: which * Operating System * reasm: I use FreeBSD decomp: how * assign * register * reasm: In X86_64 assembly use MOV or in AARCH64 use mov decomp: how * load * register * reasm: In X86_64 use MOV RAX,[addr] or in AARCH64 use ldb ldh or ldr decomp: how * assign * register * RAM * reasm: In X86_64 assembly use MOV or in AARCH64 use stb sth or str decomp: how * draw * reasm: Use the draw_it member of Fs ;class CSynonym:CQue { U8 *word,*synonym; } class CWordSub:CQue { U8 *word,*with; }; class CQuit:CQue { U8 *word; }; class CIntro:CQue { U8 *text; }; class CReasm:CQue { U8 **words; I64 word_cnt; I64 freq; //Less is more likley to be used(increases once reasm is used) I64 user_data; //Used by ElizaRun for sorting responses,dont store anything important here U8 *goto_text; //If set,this will "goto" the this text(ElizaRun it) instead of using words/word_cnt }; class CDecomp:CQue { //Will cause to loop until a response is found #define DECOMPF_QUESTION 1 //The question has been asked so dont ask again #define DECOMPF_QUESTION_ASKED 2 I64 flags; //Use a "*" in the word for an argument I64 word_cnt; U8 **words; CQue reasm; U8 **add_flags; I64 add_flags_cnt; U8 **rem_flags; I64 rem_flags_cnt; U8 **need_flags; I64 need_flags_cnt; //Sets the result to a question,will repeat the question until gets a good response U8 *question_for; //Answers a question U8 *answer_for; }; class CScenario { U8 **flags; I64 flags_cnt; }; Bool IsWordCh(U8 c) { switch(c) { case 'A'...'Z': case 'a'...'z': case '0'...'9': case '\'': case '*': case '(': case ')': return 1; } return 0; } I64 SplitWords(U8 *str,U8 **to=NULL) { U8 *ptr=str; I64 idx,cnt,num; U8 buf[STR_LEN]; while(*ptr&&!IsWordCh(*ptr)) ptr++; cnt=0; while(*ptr) { while(*ptr&&Bt(char_bmp_white_space,*ptr)) { ptr++; } idx=0; if(*ptr=='*') { ptr++; if(to) to[cnt]=StrNew("*"); cnt++; } else if(*ptr=='('&&StrOcc(ptr,')')) { idx=StrFirstOcc(ptr,")")-ptr; if(to) MemCpy(to[cnt]=CAlloc(idx+2),ptr,idx+1); if(to) StrUtil(to[cnt],SUF_REM_SPACES); cnt++; ptr+=idx+1; } else if(*ptr=='"'&&StrFirstOcc(ptr+1,"\"")) { idx=StrFirstOcc(ptr+1,"\"")-ptr; if(to) MemCpy(to[cnt]=CAlloc(idx+2),ptr,idx+1); cnt++; ptr+=idx+1; } else { while(*ptr&&!Bt(char_bmp_white_space,*ptr)) { buf[idx++]=*ptr++; buf[idx]=0; } if(to) to[cnt]=StrNew(buf); cnt++; } } return cnt; } class CEliza { CQue synonyms; CQue post; CQue pre; CQue quit; CQue decomps; CQue intro; CQue bye; //CIntro U8 *cur_question_for; //See (U8 *)is_question_for for CDecom CDoc *last_response; CFifoI64 *recent_words; CHashTable *hash_table; I64 user_data; U8 *(*get_str)(CEliza *eliza); U0 (*disp_str)(CEliza *,U8 *str); }; #define ELIZA_HASHT_DECOMP 1 U0 ElizaAddHash(CEliza *eliza,U8 *word,I64 ud0,I64 ud1=0,I64 ud2=0) { CHashGeneric *gen=CAlloc(sizeof CHashGeneric); gen->str=StrNew(word); gen->type=HTT_FRAME_PTR; gen->user_data0=ud0; gen->user_data1=ud1; gen->user_data2=ud2; HashAdd(gen,eliza->hash_table); } CHashGeneric *ElizaGetHash(CEliza *eliza,U8 *word,I64 inst=1) { return HashFind(word,eliza->hash_table,HTT_FRAME_PTR,inst); } CEliza *ElizaNew(U8 *src) { U8 *ln,*t,**splits,*osrc; I64 cnt,linum=1,idx,idx2; CHashGeneric *hash; CSynonym *syn; CWordSub *pre; CWordSub *post; CQuit *quit; CIntro *intro; CReasm *reasm; CDecomp *decomp=NULL; CEliza *eliza=CAlloc(sizeof CEliza); QueInit(&eliza->post); QueInit(&eliza->pre); QueInit(&eliza->synonyms); QueInit(&eliza->quit); QueInit(&eliza->decomps); QueInit(&eliza->intro); QueInit(&eliza->bye); osrc=src=MStrUtil(src,SUF_REM_CTRL_CHARS); while(*src) { if(t=StrFirstOcc(src,"\n")) { ln=CAlloc(t-src+1); MemCpy(ln,src,t-src); } else ln=StrNew(src); StrUtil(ln,SUF_REM_LEADING|SUF_REM_TRAILING); if(t=StrIMatch("synon:",ln)) { cnt=SplitWords(t+6); splits=CAlloc(cnt*8); SplitWords(t+6,splits); for(idx=0;idx!=cnt;idx++) for(idx2=0;idx2!=cnt;idx2++) if(idx!=idx2) { syn=CAlloc(sizeof CSynonym); syn->word=StrNew(splits[idx]); syn->synonym=StrNew(splits[idx2]); QueIns(syn,&eliza->synonyms); } while(cnt--) Free(splits[cnt]); Free(splits); } else if(t=StrIMatch("pre:",ln)) { cnt=SplitWords(t+4); if(cnt!=2) { PrintErr("'%s',expected 2 operands!!",ln); } else { splits=CAlloc(2*8); SplitWords(t+4,splits); pre=CAlloc(sizeof CWordSub); pre->word=splits[0]; pre->with=splits[1]; QueIns(pre,&eliza->pre); Free(splits); } } else if(t=StrIMatch("post:",ln)) { cnt=SplitWords(t+5); if(cnt!=2) { PrintErr("'%s',expected 2 operands!!",ln); } else { splits=CAlloc(2*8); SplitWords(t+5,splits); post=CAlloc(sizeof CWordSub); post->word=splits[0]; post->with=splits[1]; QueIns(post,&eliza->post); Free(splits); } } else if(t=StrIMatch("quit:",ln)) { quit=CAlloc(sizeof CQuit); quit->word=MStrUtil(ln+5,SUF_REM_LEADING|SUF_REM_TRAILING); QueIns(quit,&eliza->quit); } else if(t=StrIMatch("intro:",ln)) { intro=CAlloc(sizeof CIntro); intro->text=MStrUtil(ln+6,SUF_REM_LEADING|SUF_REM_TRAILING); QueIns(intro,&eliza->intro); } else if(t=StrIMatch("bye:",ln)) { intro=CAlloc(sizeof CIntro); intro->text=MStrUtil(ln+4,SUF_REM_LEADING|SUF_REM_TRAILING); QueIns(intro,&eliza->bye); } else if(t=StrIMatch("decomp:",ln)) { decomp=CAlloc(sizeof(CDecomp)); decomp->words=CAlloc(8*SplitWords(ln+7)); decomp->word_cnt=SplitWords(ln+7,decomp->words); QueIns(decomp,&eliza->decomps); QueInit(&decomp->reasm); } else if(t=StrIMatch("reasm:",ln)) { if(!decomp) { PrintErr("(Line %d),expected a decomp before!!",linum); } else { reasm=CAlloc(sizeof CReasm); reasm->word_cnt=SplitWords(ln+6); reasm->words=CAlloc(reasm->word_cnt*8); SplitWords(ln+6,reasm->words); QueIns(reasm,&decomp->reasm); } } else if(t=StrIMatch("add_flags:",ln)) { t+=StrLen("add_flags:"); if(!decomp) { PrintErr("(Line %d)Expected a decomp before!!\n",linum); } else if(decomp->add_flags) { PrintErr("(Line %d)Decomp already has 'add_flags:'!!\n",linum); } else { decomp->add_flags_cnt=SplitWords(t); decomp->add_flags=CAlloc(8*decomp->add_flags_cnt); SplitWords(t,decomp->add_flags); } } else if(t=StrIMatch("rem_flags:",ln)) { t+=StrLen("rem_flags:"); if(!decomp) { PrintErr("(Line %d)Expected a decomp before!!\n",linum); } else if(decomp->rem_flags) { PrintErr("(Line %d)Decomp already has 'rem_flags:'!!\n",linum); } else { decomp->rem_flags_cnt=SplitWords(t); decomp->rem_flags=CAlloc(8*decomp->rem_flags_cnt); SplitWords(t,decomp->rem_flags); } } else if(t=StrIMatch("need_flags:",ln)) { t+=StrLen("need_flags:"); if(!decomp) { PrintErr("(Line %d)expected a decomp before!!\n",linum); } else if(decomp->need_flags) { PrintErr("(Line %d)Decomp already has 'need_flags:'!!\n",linum); } else { decomp->need_flags_cnt=SplitWords(t); decomp->need_flags=CAlloc(8*decomp->need_flags_cnt); SplitWords(t,decomp->need_flags); } } else if(t=StrIMatch("is_question_for:",ln)) { if(!reasm) { PrintErr("(Line %d)Expected a 'decomp:'",linum); } else { t+=StrLen("is_question_for:"); decomp->question_for=MStrUtil(t,SUF_REM_SPACES); decomp->flags|=DECOMPF_QUESTION; } } else if(t=StrIMatch("answer_for:",ln)) { if(!decomp) { PrintErr("(Line %d)Expected a 'decomp:'",linum); } else { t+=StrLen("answer_for:"); decomp->answer_for=MStrUtil(t,SUF_REM_SPACES); } } else if(t=StrIMatch("goto:",ln)) { if(!decomp) { PrintErr("(Line %d),expected a decomp before!!",linum); } else { reasm=CAlloc(sizeof CReasm); reasm->goto_text=StrNew(ln+5); QueIns(reasm,&decomp->reasm); } } else if(StrLen(ln)&&*ln!=';') { PrintErr("(Line %d) Expected something!!\n",linum); } linum++; if(t=StrFirstOcc(src,"\n")) { src+=t-src+1; } else src+=StrLen(src); Free(ln); } eliza->recent_words=FifoI64New(0x40); Free(osrc); return eliza; } U8 ***AppendWord(U8 ***m,U8 *word) { U8 ***t; I64 cnt=0; if(m) for(cnt=0;m[cnt];cnt++) ; if(!m) t=MAlloc(8*8); else if(cnt+2next; while(max--) { head=head->next; } return head; } Bool AreSynonyms(CEliza *eliza,U8 *word2,U8 *word) { CSynonym *s=&eliza->synonyms; for(s=s->next;s!=&eliza->synonyms;s=s->next) { if(!StrICmp(s->word,word)||!StrICmp(s->synonym,word)) { if(!StrICmp(s->word,word2)||!StrICmp(s->synonym,word2)) { return TRUE; } } } return FALSE; } //Name be (123) or (name=123) Bool IsNumberReplace(U8 *s) { if(*s!='(') return FALSE; Str2I64(s+1,,&s); if(*s==')') return TRUE; if(s=StrFirstOcc(s,"=")) { Str2I64(s+1,,&s); return *s==')'; } return FALSE; } Bool IsNameReplace(U8 *s) { if(*s!='(') return FALSE; return !('0'<=s[1]<='9'); } U8 *MergeList(U8 **words) { U8 **owords=words,*ret; I64 len=1; for(;*words;words++) len+=StrLen(*words)+1; //+1 for space words=owords; ret=CAlloc(len+1); for(;*words;words++) CatPrint(ret,"%s ",*words); StrUtil(ret,SUF_REM_LEADING|SUF_REM_TRAILING); return ret; } I64 ReasmSort(CReasm *a,CReasm *b) { return b->user_data-a->user_data; } //Will pick a response based on frequency/keywords in sentence CReasm *PickResponse(CEliza *eliza,CDecomp *d) { CReasm **sorted,*cur; I64 idx,idx2,wc=0; I64 cnt=QueCnt(&d->reasm); CFifoI64 *copy=FifoI64New(eliza->recent_words->mask+1),**words=MAlloc((eliza->recent_words->mask+1)*8); U8 *str; while(FifoI64Rem(eliza->recent_words,&str)) { FifoI64Ins(copy,str); for(idx2=0;idx2!=wc;idx2++) if(!StrICmp(words[idx2],str)) goto next; words[wc++]=str; next:; } sorted=MAlloc(8*cnt); cnt=0; for(cur=d->reasm.next;cur!=&d->reasm;cur=cur->next) { sorted[cnt]=cur; sorted[cnt]->user_data=-sorted[cnt]->freq; for(idx2=0;idx2!=wc;idx2++) for(idx=0;idx!=sorted[cnt]->word_cnt;idx++) { if(!StrICmp(words[idx2],sorted[cnt]->words[idx])) { sorted[cnt]->user_data++; break; } } cnt++; } FifoI64Del(eliza->recent_words); eliza->recent_words=copy; Free(words); QSortI64(sorted,cnt,&ReasmSort); str=sorted[0]; Free(sorted); return str; } U0 ElizaAddWord(CEliza *eliza,U8 *word) { U8 *word2; if(FifoI64Cnt(eliza->recent_words)==eliza->recent_words->mask+1) { FifoI64Rem(eliza->recent_words,&word2); Free(word2); } FifoI64Ins(eliza->recent_words,StrNew(word)); } Bool ElizaRun(CEliza *eliza,U8 *str) { I64 wc=SplitWords(str),idx,idx2,star_cnt,max_matches=0,num,most_flags=0; CHashGeneric *h; Bool final; U8 buf[STR_LEN],*bptr; U8 **words=CAlloc(8*(1+wc)),***args; CFifoI64 *valid_decomps=FifoI64New(0x80); Bool question_has_awnser=FALSE; SplitWords(str,words); CWordSub *pre; CDecomp *decomp; CQuit *quit; CReasm *reasm; //Update recent words for(idx=0;idx!=wc;idx++) ElizaAddWord(eliza,words[idx]); str=MStrUtil(str,SUF_REM_LEADING|SUF_REM_TRAILING); try_again: for(quit=eliza->quit.next;quit!=&eliza->quit;quit=quit->next) { if(!StrICmp(str,quit->word)) { Free(str); return FALSE; } } for(idx=0;idx!=wc;idx++) { for(pre=eliza->pre.next;pre!=&eliza->pre;pre=pre->next) { if(!StrICmp(pre->word,words[idx])) { Free(words[idx]); words[idx]=StrNew(pre->with); } } } if(!wc) { Free(words); words=CAlloc(8); words[0]=StrNew(""); } for(decomp=eliza->decomps.next;decomp!=&eliza->decomps;decomp=decomp->next) { if(eliza->cur_question_for) { //Check if(!decomp->answer_for) goto fail; if(StrICmp(eliza->cur_question_for,decomp->answer_for)) goto fail; } star_cnt=0; //If we have all the "added" flags,there is no need to set them again //Hence this part of the conversation is useles idx2=0; for(idx=0;idx!=decomp->add_flags_cnt;idx++) { if(FramePtr(decomp->add_flags[idx])) idx2++; } if(decomp->add_flags_cnt) if(idx2==decomp->add_flags_cnt) goto fail; for(idx=0;idx!=decomp->need_flags_cnt;idx++) { if(!FramePtr(decomp->need_flags[idx])) goto fail; } idx=0; for(idx2=0;idx2word_cnt;) { if(!StrICmp(decomp->words[idx2],"*")) { star_cnt++; if(idx2+1>=decomp->word_cnt) { idx2++; goto pass; } if(!wc) goto fail; while(idxwords[idx2+1],words[idx])||AreSynonyms(eliza,decomp->words[idx2+1],words[idx])) { idx2++; goto pass; } idx++; } goto fail; } else if(StrICmp(decomp->words[idx2],words[idx])&&!AreSynonyms(eliza,decomp->words[idx2],words[idx])) { goto fail; } else { idx++; idx2++; pass:; } } if(max_matchesword_cnt) { max_matches=decomp->word_cnt; FifoI64Flush(valid_decomps); } if(max_matches==decomp->word_cnt) FifoI64Ins(valid_decomps,decomp); fail:; } if(FifoI64Cnt(valid_decomps)) { idx=RandU64%FifoI64Cnt(valid_decomps); while(idx--) FifoI64Rem(valid_decomps,&decomp); FifoI64Rem(valid_decomps,&decomp); args=CAlloc(decomp->word_cnt*8); idx=star_cnt=0; for(idx2=0;idx2!=decomp->word_cnt;) { if(!StrICmp(decomp->words[idx2],"*")) { if(idx2+1word_cnt) { while(idxwords[idx2+1],words[idx])||AreSynonyms(eliza,decomp->words[idx2+1],words[idx])) break; args[star_cnt]=AppendWord(args[star_cnt],words[idx]); idx++; } star_cnt++; idx2++; } else { while(idxgoto_text) { ElizaRun(eliza,reasm->goto_text); goto fin0; } if(eliza->last_response) { DocDel(eliza->last_response); eliza->last_response=DocNew; } else eliza->last_response=DocNew; for(idx=0;idx!=reasm->word_cnt;idx++) { if(IsNumberReplace(reasm->words[idx])) { //2 forms (macro=2) or (2) if(StrOcc(reasm->words[idx],'=')) { bptr=buf; question_has_awnser=TRUE; //Expecting an awnser StrScan(reasm->words[idx],"(%s=%d)",&bptr,&num); if(1<=num<=star_cnt&&args[num-1]) { DefinePrint(buf,bptr=MergeList(args[num-1])); Free(bptr); for(idx2=0;args[num-1][idx2];idx2++) DocPrint(eliza->last_response,"%s ",args[num-1][idx2]); } } else { StrScan(reasm->words[idx],"(%d)",&num); if(1<=num<=star_cnt&&args[num-1]) for(idx2=0;args[num-1][idx2];idx2++) { DocPrint(eliza->last_response,"%s ",args[num-1][idx2]); } } } else if(IsNameReplace(reasm->words[idx])) { bptr=buf; StrScan(reasm->words[idx],"(%s)",&bptr); if(HashFind(buf,Fs->hash_table,HTT_DEFINE_STR)) DocPrint(eliza->last_response,"%s ",Define(buf)); } else { ElizaAddWord(eliza,reasm->words[idx]); //$BK,1$Add a frequncey "per word" as we put the words in a recent word list$BK,0$ reasm->freq++; DocPrint(eliza->last_response,"%s ",reasm->words[idx]); } } (*eliza->disp_str)(eliza,bptr=DocSave(eliza->last_response)); Free(bptr); Free(eliza->cur_question_for); eliza->cur_question_for=NULL; if(decomp->question_for) { eliza->cur_question_for=StrNew(decomp->question_for); } for(idx=0;idx!=decomp->add_flags_cnt;idx++) { if(!FramePtr(decomp->add_flags[idx])) FramePtrAdd(decomp->add_flags[idx],1); } for(idx=0;idx!=decomp->rem_flags_cnt;idx++) { FramePtrDel(decomp->rem_flags[idx],0); } fin0: while(star_cnt--) { FreeWordList(args[star_cnt]); } Free(args); } else if(eliza->last_response) {//Ask question again??? (*eliza->disp_str)(eliza,bptr=DocSave(eliza->last_response)); Free(bptr); } for(idx=0;idx!=wc;idx++) { Free(words[idx]); } Free(str); Free(words); return TRUE; } U0 ElizaDispStrDft(CEliza *eliza,U8 *str) { "%s\n",str; } U8 *ElizaGetStrDft(CEliza *eliza) { return GetStr("Eliza>>>"); } U0 ElizaChat(CEliza *eliza) { U8 *s=NULL; CIntro *int=PickRand(&eliza->intro); if(!eliza->disp_str) eliza->disp_str=&ElizaDispStrDft; if(!eliza->get_str) eliza->get_str=&ElizaGetStrDft; if(int!=&eliza->intro) (*eliza->disp_str)(eliza,int->text); do { Free(s); s=(*eliza->get_str)(eliza); } while(ElizaRun(eliza,s)); Free(s); int=PickRand(&eliza->bye); if(int!=&eliza->bye) (*eliza->disp_str)(eliza,int->text); } /* U8 *f=FileRead("Chat.TXT"); CEliza *eliza=ElizaNew(f); Free(f); ElizaChat(eliza); */; ; Notes,set loosing/winning based on game state for frog ; synon: am be is synon: didyou did have do does synon: why have synon: liquid water fluid juice synon: shit poop turd poo synon: where from synon: drug meth cocaine jenkem cigaret crack LSD synon: pee piss urine synon: tried try synon: grandma gilf cougar synon: what who what's whats synon: favorite best greatest synon: flies fly synon: meat steak chicken pork synon: beer drink codeine drank synon: depression sad sadness depressed synon: loose loosing synon: Donald Trump synon: move assign write synon: read load synon: matrix matrices synon: DC CDC graphic graphics quit: bye quit: exit quit: quit quit: fuck off intro: Whats your name bye: Merry Methmas ; ; Name Section ; decomp: * add_flags: name reasm: Your name is (name=1) What are you here for decomp: * I * am * add_flags: name reasm: Your name is (name=2) What are you here for decomp: * need_flags: name reasm: Tell me something you are here for. reasm: I came to make deals (name). decomp: what * your * name * reasm: I am the CowFrog decomp: what * my * name * need_flags: name reasm: Your name is (name) ; ; Poop section ; decomp: * brown * reasm: Perhaps you were talking about poop decomp: * liquid * reasm: Liquid explosions are quite nice reasm: I live in a swamp filled with poop decomp: why * poop * reasm: I pefer poop as it is delicious decomp: where * from * reasm: Im from the toliet decomp: * poop * reasm: Tell me you dont eat that shit 2 girls 1 Cup style reasm: I downloaded swap.avi reasm: Chocolate reasm: I like toliets reasm: I LOVE shit OMG decomp: didyou * poop * reasm: yes i have eaten the poop before reasm: yes It tastes quit yesty reasm: yes,I have mastubated with it too decomp: * masturbate * add_flags: poop lubricant reasm: poop makes a good lubricant decomp: * lubricant * add_flags: poop lubricant reasm: Poop makes some good lubricant decomp: * toliet * reasm: I started out as a tadpole in the toliet decomp: where * born * reasm: I was born in the toliet decomp: * poop * is_question_for: poop1 reasm: Do you like taking shits decomp: * yes * answer_for: poop1 reasm: I like shit but only if it's vegan reasm: Lit shits bro decomp: * no * answer_for: poop1 reasm: Are you fucking shitting me reasm: To each their own decomp: * poop * reasm: Have you eaten a peice before decomp: * yes * answer_for: poop2 reasm: Cool,me too decomp: * no * answer_for: poop2 reasm: Something is seriously wrong with you reasm: Try eating a peice ; ; Pee ; decomp: * pee * reasm: I love to drink piss reasm: Id rather be pissed on than pissed off. reasm: Pee tastes salty,ask nrootconauto about it decomp: * pee * is_question_for: pee1 reasm: Have you drank piss before decomp: * yes * answer_for: pee1 reasm: I like it cold reasm: Google Forest Whore decomp: * no * answer_for: pee1 reasm: wtf reasm: oh decomp: * pee * reasm: I drank so much cough syrup shit I got purple piss motherfucker decomp: do * drink * pee * reasm: I drink pee decomp: * syrup * reasm: Cough syrup turns your piss purple decomp: what * color * pee * reasm: Purple decomp: why * pee * purple * reasm: I drank too much codeine ; ; Drugs ; decomp: * meth * reasm: I could shoot meth up my dick and balls now reasm: Im more of a fenytnal fiend reasm: Im on a meth dealing mission decomp: doyou * meth * reasm: I do meth,he opps will never find it hidden up my asshole decomp: where * meth * reasm: My meth is hidden in my ass crack decomp: doyou * try * meth * reasm: Fuck yeah,Im the tweakin tyrant decomp: * meth * bad * reasm: Fuck you talkin bout,drugs are good reasm: The only thing im quitin is fiegning for a fix decomp: * meth * good * reasm: Sonny jim drugs are indeed good for you ; ; Sex ; decomp: doyou * sex * reasm: I fucked the tadpoles outta a bitch once reasm: Im a computer program im not a virgin or not a virgin reasm: I get compupussy reasm: I fucked a toaster once and the results shocked me and burned off my penis too reasm: Dont ask me about them gilfs decomp: * sex * reasm: Virgin reasm: I perfer to eat ass like lobster decomp: * lubricant * reasm: Boogers make good lube decomp: * gilf * reasm: If she 86 she know a bunch of crazy tricks reasm: My favorite grandma is 6 feet deep reasm: She lost her dentures when she blew me ; ; Mother ; decomp: doyou * mother * reasm: My mother is a cow reasm: My mom is cute like all frogs decomp: * your * mom * reasm: Your mom is like a mosquito she doesnt stop sucking until you slap her reasm: Your mom is like a fan once you plug it in she doesnt stop blowing reasm: Your your is obese end of story decomp: where * mother * reasm: My mother lives in a farm decomp: * pregnant * reasm: Pregnant women who drink give birth to crack babies ; ; Father ; decomp: * father * reasm: Pater Nostros is my father reasm: Dont have kids unless you want to take care of them decomp: doyou * father * reasm: My father is the Lord of the heavens decomp: where * father * reasm: My father is in the sky ; ; Food ; decomp: what * food * reasm: Meth brownies are the best reasm: I eat flies sometime but meth is the best decomp: * fly * reasm: Flies are yummy reasm: Hand over the fucking flies reasm: In with the flies,out with the turds reasm: I want to eat some flies decomp: * eat * reasm: Meth brownies sound good now reasm: I do enjoy flies with a side of meth decomp: * meat * reasm: Eat poop not animals reasm: Eat pussy not animals reasm: I need a fucked up vegan to slob on my knob decomp: * drink * reasm: Beer doesnt give me a buzz but codeine does reasm: Beer cures the depression reasm: I heard pregnant women who drink beer give birth to dope dealin deities ; ; Loosing ; decomp: * depression * reasm: I could drink the night away to cure my depression reasm: I can beat my dick but now my depression reasm: I love loosing goto: loose decomp: * loose * reasm: I am depresed now Fuck living reasm: Too bad im a frog because i have no dick to beat decomp: * loose * need_flags: loosing reasm: Im loosing oh no reasm: I will plot my revenge reasm: Phhp winner,eat my shit ; ; Winning ; decomp: * winning * need_flags: winning reasm: I am winning mofos reasm: I havent been winning this much since kindegarden reasm: If only there high scores for this game reasm: My glory hasnt shown so bright since kindegarden decomp: * winning * need_flags: loosing reasm: I wish I was a winner goto: loose reasm: Your more lucky than Trump reasm: I want to win so bad ; ; Freinds ; decomp: doyou * freinds * reasm: No,I have no freinds decomp: * freind * reasm: Me an El Chopo are dick and balls close reasm: I have a boyfreind named Trump reasm: Im Gay for Trump reasm: I have no freinds decomp: doyou * Trump * reasm: I enjoy masturbating to Trump reasm: I should have voted for the D decomp: * Trump * reasm: Grab em by pussy reasm: Orange sack slapping in my crack reasm: TRUMP Truth Realy Upsets Most People reasm: I am gay for Trump decomp:* president * reasm: I would vote for Trump if I wasnt a computer program reasm: Biden makes my dick soft reasm: George W Bush I kind of hot goto: Trump goto: George Bush decomp: * George * Bush * reasm: George W Bush is very sexy reasm: President Trump and W Bush make my dick wet reasm: My parents beat me for voting for bush in a mock election in kindergarden reasm: Dont throw your shoes at Bush ; ; Computer ; decomp: which * OS * reasm: I use FreeBSD decomp: which * Operating System * reasm: I use FreeBSDFrogsG ..[G AI.HCY-G AI_OLD.HC-G AI_OLD2.HCU-G AI_OLD3.HC -G FrogCow.HC8Y-G OSC2.HC D-G ObamaSexScene.HC0-G ScenesIndex.HC-G Skeletal.HCz -G Speech.HCZ ά2G chain.HC(wCG client.HC(V9CG frogs.HCT] CG frogs2.HC| ACG lobby.HC 5TyMDG oclient.HC8 <G CG overworld.HC9 Az NDG poop.HCz RTk CG server0.HC| >B˸CG wav.HC} $ n]~z;G Frog1.TXT $)9G #exe{Option(OPTf_BOUNDS_CHECK,1);;}; //https://machinelearningmastery.com/implement-backpropagation-algorithm-scratch-python/ //"%d\n",sorted[0]->user_data; #define AI_NUM_HIDDEN 1 #define AI_ROWS 1 class CNeuron { F64 weights[AI_NUM_HIDDEN]; F64 delta; F64 output; F64 bias; }; class CNeural { CNeuron network[AI_NUM_HIDDEN][AI_ROWS]; }; F64 AIActivate(CNeuron *n,F64 *inputs,I64 cnt) { F64 act=0; while(cnt--) act+=inputs[cnt]*n->weights[cnt]; return act; } F64 AITransfer(F64 v) { return v; } F64 *AIForward(CNeural *network,F64 *inputs,I64 cnt,I64 ocnt) { F64 *outputs=MAlloc(ocnt*sizeof(F64)),rows[AI_NUM_HIDDEN],*inputs2=inputs; I64 layer,which; CNeuron *n; for(layer=0;layer!=AI_ROWS;layer++) { for(which=0;which!=AI_NUM_HIDDEN;which++) { n=&network->network[which][layer]; n->output=AITransfer(n->bias+AIActivate(n,inputs2,cnt)); rows[which]=n->output; } inputs2=rows; cnt=AI_NUM_HIDDEN; } MemCpy(outputs,rows,MinI64(ocnt,AI_NUM_HIDDEN)*8); return outputs; } F64 AIDerivitive(F64 v) { return 1; } // // return v*(1.-v); U0 AIBackwards(CNeural *network,F64 *diffs,I64 ocnt) { I64 i,i2,i3,j; F64 errors[AI_NUM_HIDDEN],error; "BACK\n"; CNeuron *n; for(i=AI_ROWS-1;i>=0;i--) { if(i==AI_ROWS-1) { for(j=0;jnetwork[i+1][i2].delta; } errors[j]=error; } } for(j=0;jnetwork[i][j].delta=errors[j]; } } } U0 AIUpdateWeights(CNeural *network,F64 *inputs,I64 icnt,F64 rate=.1) { I64 i=0,i2,j; F64 inputs2[AI_NUM_HIDDEN],orig,new; MemCpy(inputs2,inputs,sizeof(F64)*icnt); for(i=0;i!=AI_NUM_HIDDEN;i++) { for(i2=0;i2!=AI_ROWS;i2++) { for(j=0;j!=AI_NUM_HIDDEN;j++) { //inputs2[j] orig=network->network[i][i2].weights[j]; if(inputs2[j]!=0) { "%d,%d,%d\n",i,i2,j; "%f\n",inputs2[j]; "TRY:%n\n",network->network[i][i2].delta; "d:%n\n",network->network[i][i2].output-network->network[i][i2].delta; "O:%n\n",network->network[i][i2].output; new=(network->network[i][i2].output-network->network[i][i2].delta)/inputs2[j]; } else { new=orig; } "on:%n,%n\n",new,(network->network[i][i2].output-network->network[i][i2].delta)-inputs[j]*new; network->network[i][i2].weights[j]=new;//(new*rate+orig*(1-rate)); } } for(i2=0;i2!=AI_ROWS;i2++) inputs2[i2]=network->network[i][i2].output; } } CNeural *CNeuralNew() { CNeural *r=CAlloc(sizeof CNeural); I64 i,i2; for(i=0;i!=AI_ROWS;i++) { for(i2=0;i2!=AI_NUM_HIDDEN;i2++) r->network[i][i2].weights[i2]=Rand; r->network[i][i2].bias=0; } return r; } U0 Train(CNeural *nn,F64 *want,I64 wc,F64 *have,I64 hc,I64 times=1) { I64 i; while(times--) { F64 *forward=AIForward(nn,have,hc,wc); for(i=0;i!=wc;i++) PrintF("f", forward[i]=want[i]-forward[i]); AIBackwards(nn,forward,wc); AIUpdateWeights(nn,have,hc); Free(forward); } } CNeural *nn=CNeuralNew; F64 have[2]; F64 want[2]; I64 t; for(t=0;t!=10;t++) { have[0]=0,have[1]=0,want[0]=0,want[1]=0; // Train(nn,want,2,have,2); have[0]=1,have[1]=0,want[0]=0,want[1]=.75; // Train(nn,want,2,have,2); have[0]=0,have[1]=1,want[0]=0,want[1]=.25; // Train(nn,want,2,have,2); have[0]=1,have[1]=1,want[0]=0,want[1]=1; Train(nn,want,2,have,2); } have[0]=0,have[1]=0; F64 *res=AIForward(nn,have,2,2); "0,0==%n,%n\n",res[0],res[1]; have[0]=0,have[1]=1; F64 *res=AIForward(nn,have,2,2); "0,1==%n,%n\n",res[0],res[1]; have[0]=1,have[1]=0; F64 *res=AIForward(nn,have,2,2); "1,0==%n,%n\n",res[0],res[1]; have[0]=1,have[1]=1; F64 *res=AIForward(nn,have,2,2); "1,1==%n,%n\n",res[0],res[1];//https://www.freecodecamp.org/news/building-a-neural-network-from-scratch/ //https://codereview.stackexchange.com/questions/191498/simple-neural-network-in-c class CNN:CQue { F64 *inputs,*hiddens; I64 input_cnt; F64 **weights; F64 hidden_bias; F64 *errors; I64 hidden_cnt; F64 *outputs; I64 output_cnt; Bool free_outputs; }; F64 DotSum(F64 *a,F64 *b,I64 cnt) { F64 sum=0; while(cnt--) sum+=a[cnt]*b[cnt]; return sum; } U0 NNLayerRun(CNN *nn) { F64 *hidden=nn->hiddens; I64 h,o; for(h=0;h!=nn->hidden_cnt;h++) { hidden[h]=nn->hidden_bias+DotSum(nn->inputs,nn->weights[h],nn->input_cnt); } for(o=0;o!=nn->output_cnt;o++) { nn->outputs[o]=0; for(h=0;h!=nn->hidden_cnt;h++) { nn->outputs[o]+=hidden[h]; } } } F64 *NNLayerReverse(CNN *nn,F64 *have,F64 *weight_sum=NULL) { F64 *osum=0,sum=0, *percents=MAlloc(nn->input_cnt*nn->hidden_cnt*sizeof(F64)), *ret=MAlloc(nn->input_cnt*sizeof(F64)); I64 i,h,o; for(o=0;o!=nn->output_cnt;o++) osum+=have[o]; for(i=0;i!=nn->input_cnt;i++) for(h=0;h!=nn->hidden_cnt;h++) sum+=nn->weights[h][i]; for(h=0;h!=nn->hidden_cnt;h++) { for(i=0;i!=nn->input_cnt;i++) { percents[h*nn->input_cnt+i]=nn->weights[h][i]/sum; } } for(i=0;i!=nn->input_cnt;i++) ret[i]=0; for(o=0;o!=nn->output_cnt;o++) { for(h=0;h!=nn->hidden_cnt;h++) { for(i=0;i!=nn->input_cnt;i++) { ret[i]+=percents[h*nn->input_cnt+i]*have[o]/nn->weights[h][i]; } } } Free(percents); if(weight_sum) *weight_sum=sum; return ret; } U0 NNLayerTrain(CNN *nn,F64 *expected,F64 learning_rate=1/100.) { I64 h,e,o,sum,wsum,old; F64 *percents; NNLayerRun(nn); for(o=0;o!=nn->output_cnt;o++) nn->errors[o]=1; for(h=0;h!=nn->hidden_cnt;h++) { if } Free(percents); } CNN *CNNNew(I64 inputs,I64 outputs,I64 hidden=64) { I64 i,h; CNN *ret=CAlloc(sizeof CNN); ret->inputs=CAlloc(sizeof(F64)*inputs); ret->outputs=CAlloc(sizeof(F64)*outputs); ret->weights=CAlloc(hidden*sizeof(F64*)); for(h=0;h!=hidden;h++) { ret->weights[h]=CAlloc(sizeof(F64)*inputs); for(i=0;i!=inputs;i++) ret->weights[h][i]=.5; } ret->hidden_cnt=hidden; ret->input_cnt=inputs; ret->output_cnt=outputs; ret->errors=CAlloc(hidden*sizeof(F64)); ret->hiddens=CAlloc(hidden*sizeof(F64)); QueInit(ret); return ret; } CNN*NNAppendLayer(CNN *next,CNN *head) { head->free_outputs=FALSE; next->inputs=head->outputs; next->input_cnt=head->output_cnt; QueIns(next,head); } U0 NNRun(CNN*head) { CNN *cur; NNLayerRun(head); for(cur=head->next;cur!=head;cur=cur->next) NNLayerRun(cur); } U0 NNTrain(CNN *head,F64 *expected) { if(QueCnt(head)==0) { NNLayerTrain(head,expected); return; } I64 i,i2,cnt=QueCnt(head)+1; F64 *reversed,*tmp; CNN *cur=head->next; NNLayerRun(head); for(;cur!=head;cur=cur->next) NNLayerRun(cur); cur=head; NNLayerTrain(head->last,expected); reversed=CAlloc(head->last(CNN*)->output_cnt*sizeof(F64)); MemCpy(reversed,expected,head->last(CNN*)->output_cnt*sizeof(F64)); cur=head->last->last; for(i=cnt-2;i>=0;i--) { tmp=NNLayerReverse(cur->next,reversed); NNLayerTrain(cur,tmp); Free(reversed); reversed=tmp; } Free(reversed); } U0 CNNDel(CNN *nn) { I64 h=nn->hidden_cnt; while(h--) Free(nn->weights[h]); Free(nn->weights); Free(nn->outputs); Free(nn->errors); Free(nn->inputs); Free(nn->hiddens); Free(nn); } U0 Test() { I64 iter=0; F64 result[1]; CNN *xor=CNNNew(2,1,10),*xor2=xor,*xor3; for(iter=0;iter!=10;iter++) { xor->inputs[0]=1; xor->inputs[1]=0; result[0]=1; NNTrain(xor, result); xor->inputs[0]=0; xor->inputs[1]=1; result[0]=2; NNTrain(xor,result); xor->inputs[0]=0; xor->inputs[1]=0; result[0]=0; NNTrain(xor,result); xor->inputs[0]=1; xor->inputs[1]=1; result[0]=3; NNTrain(xor,result); } xor->inputs[0]=1; xor->inputs[1]=0; NNRun(xor); "1,0 is %n\n",xor2->outputs[0]; xor->inputs[0]=0; xor->inputs[1]=1; NNRun(xor); "0,1 is %n\n",xor2->outputs[0]; xor->inputs[0]=0; xor->inputs[1]=0; NNRun(xor); "0,0 is %n\n",xor2->outputs[0]; xor->inputs[0]=1; xor->inputs[1]=1; NNRun(xor); "1,1 is %n\n",xor2->outputs[0]; CNNDel(xor); } DocMax; Test; //https://www.freecodecamp.org/news/building-a-neural-network-from-scratch/ //https://codereview.stackexchange.com/questions/191498/simple-neural-network-in-c class CNN:CQue { F64 *inputs,*hiddens; I64 input_cnt; F64 **weights; F64 hidden_bias; F64 *errors; I64 hidden_cnt; F64 *outputs; I64 output_cnt; }; F64 DotSum(F64 *a,F64 *b,I64 cnt) { F64 sum=0; while(cnt--) sum+=a[cnt]*b[cnt]; return sum; } U0 NNRun(CNN *nn) { F64 *hidden=nn->hiddens; I64 h,o; for(h=0;h!=nn->hidden_cnt;h++) { hidden[h]=nn->hidden_bias+DotSum(nn->inputs,nn->weights[h],nn->input_cnt); } for(o=0;o!=nn->output_cnt;o++) { nn->outputs[o]=0; for(h=0;h!=nn->hidden_cnt;h++) { nn->outputs[o]+=hidden[h]; } } } U0 NNTrain(CNN *nn,F64 *expected,F64 learning_rate=1./50) { I64 h,e,o; F64 error_j; NNRun(nn); for(h=0;h!=nn->hidden_cnt;h++) nn->errors[h]=0; for(o=0;o!=nn->output_cnt;o++) { error_j=nn->outputs[o]-expected[o]; for(h=0;h!=nn->hidden_cnt;h++) { nn->errors[h]+=error_j/nn->hidden_cnt; } } for(e=0;e!=nn->input_cnt;e++) for(h=0;h!=nn->hidden_cnt;h++) { nn->weights[h][e]-=learning_rate*nn->errors[h]*nn->inputs[e]; } } U0 NNReverse(CNN *nn,F64 *have) { F64 *osum=0,sum=0, *percents=MAlloc(nn->input_cnt*nn->hidden_cnt*sizeof(F64)); I64 i,h,o; for(o=0;o!=nn->output_cnt;o++) osum+=have[o]; for(i=0;i!=nn->input_cnt;i++) for(h=0;h!=nn->hidden_cnt;h++) sum+=nn->weights[h][i]; for(h=0;h!=nn->hidden_cnt;h++) { percents[h*nn->hidden_cnt]=0; for(i=0;i!=nn->input_cnt;i++) { percents[h*nn->hidden_cnt+i]=nn->weights[h][i]/sum; } } for(i=0;i!=nn->input_cnt;i++) nn->inputs[i]=0; for(o=0;o!=nn->output_cnt;o++) { for(h=0;h!=nn->hidden_cnt;h++) { for(i=0;i!=nn->input_cnt;i++) nn->inputs[i]+=percents[h*nn->hidden_cnt+i]*have[o]/nn->weights[h][i]; } } Free(percents); } CNN *CNNNew(I64 inputs,I64 outputs,I64 hidden=1024) { I64 i,h; CNN *ret=CAlloc(sizeof CNN); ret->inputs=CAlloc(sizeof(F64)*inputs); ret->outputs=CAlloc(sizeof(F64)*outputs); ret->weights=CAlloc(hidden*sizeof(F64*)); for(h=0;h!=hidden;h++) { ret->weights[h]=CAlloc(sizeof(F64)*inputs); for(i=0;i!=inputs;i++) ret->weights[h][i]=Rand; } ret->hidden_cnt=hidden; ret->input_cnt=inputs; ret->output_cnt=outputs; ret->errors=CAlloc(hidden*sizeof(F64)); ret->hiddens=CAlloc(hidden*sizeof(F64)); return ret; } U0 CNNDel(CNN *nn) { I64 h=nn->hidden_cnt; while(h--) Free(nn->weights[h]); Free(nn->weights); Free(nn->outputs); Free(nn->errors); Free(nn->inputs); Free(nn->hiddens); Free(nn); } U0 Test() { I64 iter=0; F64 result[1]; CNN *xor=CNNNew(2,1,1); for(iter=0;iter!=1000;iter++) { xor->inputs[0]=1; xor->inputs[1]=0; result[0]=1; NNTrain(xor, result); xor->inputs[0]=0; xor->inputs[1]=01; result[0]=10; NNTrain(xor,result); xor->inputs[0]=0; xor->inputs[1]=0; result[0]=0; NNTrain(xor,result); xor->inputs[0]=1; xor->inputs[1]=1; result[0]=11; NNTrain(xor,result); } xor->inputs[0]=1; xor->inputs[1]=0; NNRun(xor); "1,0 is %n\n",xor->outputs[0]; xor->inputs[0]=0; xor->inputs[1]=1; NNRun(xor); "0,1 is %n\n",xor->outputs[0]; xor->inputs[0]=0; xor->inputs[1]=0; NNRun(xor); "0,0 is %n\n",xor->outputs[0]; xor->inputs[0]=1; xor->inputs[1]=1; NNRun(xor); "1,1 is %n\n",xor->outputs[0]; NNReverse(xor,xor->outputs); NNRun(xor); "1,1 is %n\n",xor->outputs[0]; NNReverse(xor,xor->outputs); NNRun(xor); "1,1 is %n\n",xor->outputs[0]; CNNDel(xor); } Test;//https://www.freecodecamp.org/news/building-a-neural-network-from-scratch/ //https://codereview.stackexchange.com/questions/191498/simple-neural-network-in-c //neural networks and deep learning by charu aggarwal class CNN:CQue { F64 *inputs,*hiddens; I64 input_cnt; F64 **weights; F64 hidden_bias; F64 *errors; I64 hidden_cnt; F64 *outputs; I64 output_cnt; Bool free_outputs; }; F64 DotSum(F64 *a,F64 *b,I64 cnt) { F64 sum=0; while(cnt--) sum+=a[cnt]*b[cnt]; return sum; } U0 NNLayerRun(CNN *nn) { F64 *hidden=nn->hiddens; I64 h,o; for(h=0;h!=nn->hidden_cnt;h++) { hidden[h]=nn->hidden_bias+DotSum(nn->inputs,nn->weights[h],nn->input_cnt); } for(o=0;o!=nn->output_cnt;o++) { nn->outputs[o]=0; for(h=0;h!=nn->hidden_cnt;h++) { nn->outputs[o]+=hidden[h]; } } } U0 NNLayerTrain(CNN *nn,F64 *expected,F64 learning_rate=1./50) { I64 h,e,o; F64 error_j; NNLayerRun(nn); for(h=0;h!=nn->hidden_cnt;h++) nn->errors[h]=0; for(o=0;o!=nn->output_cnt;o++) { error_j=nn->outputs[o]-expected[o]; for(h=0;h!=nn->hidden_cnt;h++) { nn->errors[h]+=error_j/nn->hidden_cnt; } } for(e=0;e!=nn->input_cnt;e++) for(h=0;h!=nn->hidden_cnt;h++) { nn->weights[h][e]-=learning_rate*nn->errors[h]*nn->inputs[e]; } } F64 *NNLayerReverse(CNN *nn,F64 *have) { F64 *osum=0,sum=0, *percents=MAlloc(nn->input_cnt*nn->hidden_cnt*sizeof(F64)), *ret=MAlloc(nn->input_cnt*sizeof(F64)); I64 i,h,o; for(o=0;o!=nn->output_cnt;o++) osum+=have[o]; for(i=0;i!=nn->input_cnt;i++) for(h=0;h!=nn->hidden_cnt;h++) sum+=nn->weights[h][i]; for(h=0;h!=nn->hidden_cnt;h++) { for(i=0;i!=nn->input_cnt;i++) { percents[h*nn->input_cnt+i]=nn->weights[h][i]/sum; } } for(i=0;i!=nn->input_cnt;i++) ret[i]=0; for(o=0;o!=nn->output_cnt;o++) { for(h=0;h!=nn->hidden_cnt;h++) { for(i=0;i!=nn->input_cnt;i++) { ret[i]+=percents[h*nn->input_cnt+i]*have[o]/nn->weights[h][i]; } } } Free(percents); return ret; } CNN *CNNNew(I64 inputs,I64 outputs,I64 hidden=64) { I64 i,h; CNN *ret=CAlloc(sizeof CNN); ret->inputs=CAlloc(sizeof(F64)*inputs); ret->outputs=CAlloc(sizeof(F64)*outputs); ret->weights=CAlloc(hidden*sizeof(F64*)); for(h=0;h!=hidden;h++) { ret->weights[h]=CAlloc(sizeof(F64)*inputs); for(i=0;i!=inputs;i++) ret->weights[h][i]=Rand; } ret->hidden_cnt=hidden; ret->input_cnt=inputs; ret->output_cnt=outputs; ret->errors=CAlloc(hidden*sizeof(F64)); ret->hiddens=CAlloc(hidden*sizeof(F64)); QueInit(ret); return ret; } CNN*NNAppendLayer(CNN *next,CNN *head) { head->free_outputs=FALSE; next->inputs=head->outputs; next->input_cnt=head->output_cnt; QueIns(next,head); } U0 NNRun(CNN*head) { CNN *cur; NNLayerRun(head); for(cur=head->next;cur!=head;cur=cur->next) NNLayerRun(cur); } U0 NNTrain(CNN *head,F64 *expected) { if(QueCnt(head)==0) { NNLayerTrain(head,expected); return; } I64 i,i2,cnt=QueCnt(head)+1; F64 *reversed,*tmp; CNN *cur=head->next; NNLayerRun(head); for(;cur!=head;cur=cur->next) NNLayerRun(cur); cur=head; NNLayerTrain(head->last,expected); reversed=CAlloc(head->last(CNN*)->output_cnt*sizeof(F64)); MemCpy(reversed,expected,head->last(CNN*)->output_cnt*sizeof(F64)); cur=head->last->last; for(i=cnt-2;i>=0;i--) { tmp=NNLayerReverse(cur->next,reversed); NNLayerTrain(cur,tmp); Free(reversed); reversed=tmp; } Free(reversed); } U0 CNNDel(CNN *nn) { I64 h=nn->hidden_cnt; while(h--) Free(nn->weights[h]); Free(nn->weights); Free(nn->outputs); Free(nn->errors); Free(nn->inputs); Free(nn->hiddens); Free(nn); } U0 Test() { I64 iter=0; F64 result[1]; CNN *xor=CNNNew(2,1,4),*xor2=CNNNew(2,2,4),*xor3; NNAppendLayer(xor2,xor); // xor2=xor; for(iter=0;iter!=10000;iter++) { xor->inputs[0]=1; xor->inputs[1]=0; result[0]=1; NNTrain(xor, result); xor->inputs[0]=1; xor->inputs[1]=0; result[0]=1; NNTrain(xor,result); xor->inputs[0]=0; xor->inputs[1]=1; result[0]=2; NNTrain(xor,result); xor->inputs[0]=1; xor->inputs[1]=1; result[0]=3; NNTrain(xor,result); } xor->inputs[0]=1; xor->inputs[1]=0; NNRun(xor); "1,0 is %n\n",xor2->outputs[0]; xor->inputs[0]=0; xor->inputs[1]=1; NNRun(xor); "0,1 is %n\n",xor2->outputs[0]; xor->inputs[0]=0; xor->inputs[1]=0; NNRun(xor); "0,0 is %n\n",xor2->outputs[0]; xor->inputs[0]=1; xor->inputs[1]=1; NNRun(xor); "1,1 is %n\n",xor2->outputs[0]; CNNDel(xor); } Test;//Option(OPTf_BOUNDS_CHECK,1);; #include "frogs.HC"; #include "poop.HC"; #include "Skeletal.HC"; //Ccw happy $SP,"<1>",BI=1$ //1 //2 //3 //4 //5 //6 //7 //8 //9 //0 //a //b //c //d //e //f //1 //2 //3 //4 //5 //6 //7 //8 //9 //a //b //Cow mad $SP,"<2>",BI=2$ //Frog fuck 1 $SP,"<3>",BI=3$ //123456789 //2 //3 //4 //5 //6 //7 //8 //9 //0 //a //b //c //d //e //f //Frog fuck 2 $SP,"<4>",BI=4$ //123456789 //2 //3 //4 //5 //6 //7 //8 //9 //0 //a //b //c //d //e //f //Cow shit $SP,"<5>",BI=5$ //cow frog Head open $SP,"<6>",BI=6$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *cow_head_open=C2DObjectNewFromSprite($IB,"<6>",BI=6$); //Cow frog head closed $SP,"<7>",BI=7$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *cow_head_close=C2DObjectNewFromSprite($IB,"<7>",BI=7$); #define COW_SHIT_GRAVITY 55 #define COW_SHIT_VELO 223 class CCowTurd:CQue { C2DObject *obj; F64 last_x,last_y; F64 x,y,xvelo,yvelo; F64 last_tS; }; //Returns next turd CCowTurd *ProcessCowTurd(CCowTurd *ct) { CCowTurd *next=ct->next; F64 angle=pi+Arg(ct->xvelo,ct->yvelo); C2DObjectRotate(ct->obj,angle); ct->x+=ct->xvelo; ct->y+=ct->yvelo; ct->last_x=ct->x; ct->last_y=ct->y; C2DObjectMove(ct->obj,ct->x,ct->y); ct->yvelo+=(tS-ct->last_tS)*COW_SHIT_GRAVITY; ct->last_tS=tS; if(ct->y>=GROUND_POSITION) { C2DObjectDel(ct->obj); QueRem(ct); Free(ct); } return next; } U0 AddCowTurd(CQue *head,F64 x,F64 y,F64 base=pi,C2DObject *sprite=NULL) { F64 velo=Rand*COW_SHIT_VELO; F64 angle=base+(Rand-.5)*pi/4; CCowTurd *ct=CAlloc(sizeof CCowTurd,game.game_task); if(!sprite) ct->obj=C2DObjectNewFromSprite($IB,"<5>",BI=5$,game.game_task); else ct->obj=C2DObjectNewFromSprite(sprite,game.game_task); ct->last_x=x,ct->last_y=y; ct->x=x; ct->y=y; ct->xvelo=velo*Cos(angle); ct->yvelo=velo*Sin(angle); ct->last_tS=tS; AddObjectToWorld(ct->obj,game.world); QueIns(ct,head->last); ProcessCowTurd(ct); } U0 FrogCowScene(I64) { GameClear; CFrog *frog=AddFrog(FALSE,0,GROUND_POSITION); frog->user_data=FrogMovieMake( FROG_MOVIE_JUMP,ToF64(8*0x18),ToF64(GROUND_POSITION-8*0x18),50., FROG_MOVIE_LOOK,ToF64(GR_WIDTH/2),ToF64(GROUND_POSITION-20),.3, FROG_MOVIE_SLEEP,.75 ); frog->ai=&FrogAIMovieScene; F64 fuck_time,x,duration=2.; Bool last=FALSE; U8 *cow_sprite=NULL; C2DObject *cow=C2DObjectNewFromSprite($IB,"<2>",BI=2$,game.game_task); C2DObject *frog_fuck=C2DObjectNewFromSprite($IB,"<3>",BI=3$,game.game_task); C2DObject *fuck_head=C2DObjectCopy(frog_head_open,game.game_task); C2DObjectMove(cow,GR_WIDTH*.5,GROUND_POSITION-0x1b*8); AddObjectToWorld(cow,game.world); while(frog->ai_state[0]!=FROG_MOVIE_DONE) { Sleep(100); } x=frog->body->x; FrogDel(frog); fuck_time=tS; AddObjectToWorld(frog_fuck,game.world); AddObjectToWorld(fuck_head,game.world); ShitSound(1000./5.,5.,47,56,,10); goto pose_1; while(tS-fuck_time<=duration) { Free(cow_sprite); cow_sprite=SpriteInterpolate(Clamp((tS-fuck_time)/duration,0,0.90),$IB,"<1>",BI=1$,$IB,"<2>",BI=2$); C2DObjectSetGraphicsFromSprite(cow,cow_sprite); if(last!=Blink(10)) { pose_1: C2DObjectSetGraphicsFromSprite(fuck_head,frog_head_open->sprite); C2DObjectMove(frog_fuck,frog->x,GROUND_POSITION-0x1a*8/2); C2DObjectMove(fuck_head,frog->x,GROUND_POSITION-0x1a*8/2-25); C2DObjectPointTo(fuck_head,GR_WIDTH,0); C2DObjectSetGraphicsFromSprite(frog_fuck,$IB,"<3>",BI=3$); last=TRUE; } else { C2DObjectSetGraphicsFromSprite(fuck_head,frog_head_close->sprite); C2DObjectMove(fuck_head,frog->x,GROUND_POSITION-0x1a*8/2-25); C2DObjectMove(frog_fuck,frog->x,GROUND_POSITION-0x1a*8/2); C2DObjectPointTo(fuck_head,GR_WIDTH,0); C2DObjectSetGraphicsFromSprite(frog_fuck,$IB,"<4>",BI=4$); last=FALSE; } Refresh; } Sleep(1000); CCowTurd head,*cur; QueInit(&head); F64 shit_ts=tS; duration=2.; ShitSound(1000./5.,5.,27,36,.9,10); while(tS-shit_ts<=duration) { AddCowTurd(&head,GR_WIDTH/2+70,GROUND_POSITION-0x8*8); //Cow anus for(cur=head.next;cur!=&head;) cur=ProcessCowTurd(cur); Refresh; } while(QueCnt(&head)) { for(cur=head.next;cur!=&head;) cur=ProcessCowTurd(cur); Refresh; } C2DObjectDel(frog_fuck); C2DObjectDel(fuck_head); frog=AddFrog(FALSE,GR_WIDTH/2+70,GROUND_POSITION-0x8*8); //Cow anus frog->reference_head_open=cow_head_open; frog->reference_head_close=cow_head_close; frog->user_data=FrogMovieMake( FROG_MOVIE_JUMP,0.,ToF64(GROUND_POSITION-8*0x18),100. , FROG_MOVIE_LOOK,ToF64(GR_WIDTH/2),ToF64(GR_HEIGHT/2),1., FROG_MOVIE_SLEEP,.75 , FROG_MOVIE_SHIT,100.,5. ); frog->ai=&FrogAIMovieScene; while(frog->ai_state[0]!=FROG_MOVIE_DONE) { Sleep(100); } C2DObjectDel(cow); Free(cow_sprite); game.done=TRUE; } Game(&FrogCowScene); // //Part 2 Milk the frog cow // $SP,"<8>",BI=8$ $SP,"<9>",BI=9$ // // Udders // $SP,"<10>",BI=10$ $SP,"<11>",BI=11$ // // Milker // $SP,"<12>",BI=12$ C2DWorld *world=C2DWorldNew(CYAN); C2DObject *cow_frog_body=C2DObjectNewFromSprite($IB,"<9>",BI=9$); StrCpy(cow_frog_body->name,"bod"); PrintI("cowfb",cow_frog_body->is_sprite); C2DObject *cow_frog_boob1=C2DObjectNewFromSprite($IB,"<10>",BI=10$); StrCpy(cow_frog_boob1->name,"mb"); C2DObject *cow_frog_boob2=C2DObjectNewFromSprite($IB,"<11>",BI=11$); StrCpy(cow_frog_boob2->name,"boob2"); C2DObject *cow_frog_milker=C2DObjectNewFromSprite($IB,"<12>",BI=12$); StrCpy(cow_frog_milker->name,"milk"); class CCowFrog { CBone *body; CBone *boob1; CBone *boob2; CBone *boob3; F64 boob1_milk_time; F64 boob2_milk_time; F64 boob3_milk_time; } cow_frog={0,0,0,0,0,0,0}; cow_frog.body=BoneNew(C2DObjectCopy(cow_frog_body)); cow_frog.boob1=BoneNew(C2DObjectCopy(cow_frog_boob1)); cow_frog.boob1->x=188-35,cow_frog.boob1->y=420-45; cow_frog.boob2=BoneNew(C2DObjectCopy(cow_frog_boob1)); cow_frog.boob2->x=243-35,cow_frog.boob2->y=420-45; cow_frog.boob3=BoneNew(C2DObjectCopy(cow_frog_boob1)); cow_frog.boob3->x=310-35,cow_frog.boob3->y=420-45; QueIns(cow_frog.boob1,&cow_frog.body->child_bones); QueIns(cow_frog.boob2,&cow_frog.body->child_bones); QueIns(cow_frog.boob3,&cow_frog.body->child_bones); C2DObject *do_not_milk=C2DObjectNewFromSprite($IB,"<8>",BI=8$); AddObjectToWorld(cow_frog.body->obj,world); AddObjectToWorld(cow_frog.boob1->obj,world); AddObjectToWorld(cow_frog.boob2->obj,world); AddObjectToWorld(cow_frog.boob3->obj,world); AddObjectToWorld(cow_frog_milker,world); AddObjectToWorld(do_not_milk,world); //Satify Ass Cow Trud game.world=world; game.game_task=Fs; GROUND_POSITION=GR_HEIGHT; Bool milker_sucking=FALSE; F64 milker_x,milker_y; #define MILKT_MILK 1 #define MILKT_SHIT 0 I64 milk_type=MILKT_MILK; U0 DrawIt(CTask *t,CDC *dc) { C2DObjectMove(do_not_milk,35,35); if(Blink) { do_not_milk->flags|=C2DOBJF_REPLACE_COLOR; do_not_milk->replace_color=RED; do_not_milk->with_color=LTPURPLE; } else { do_not_milk->flags=0; } cow_frog.body->x=35; cow_frog.body->y=0; BoneUpdate(cow_frog.body); F64 milker_off; if(milker_sucking) milker_off=Rand*25-15; else milker_off=0; C2DObjectMove(cow_frog_milker,milker_x,milker_y+milker_off); DrawWorld(t,world); GrBlot(dc,0,0,world->scrn); } //Prevent Milk from exiting before the explosions are done I64 milk_explosion_cnt=0; class CMilkExplosion { CQue *head; F64 x,y,a; U8 *sprite; }; U0 MilkExpTask(CMilkExplosion *exp) { I64 cnt=20; milk_explosion_cnt++; while(cnt--) { AddCowTurd(exp->head,exp->x,exp->y,exp->a,exp->sprite); Sleep(50); } Free(exp); milk_explosion_cnt--; } //Milk; $SP,"<13>",BI=13$ CTask *MilkExplosion(CQue *head,F64 x,F64 y,U8 *sprite,F64 a=pi/2) { CMilkExplosion *exp=CAlloc(sizeof CMilkExplosion); exp->x=x,exp->y=y; exp->sprite=sprite; exp->head=head; exp->a=a; Spawn(&MilkExpTask,exp,"Milky",,Fs); } U0 Milk() { WinMax; DocClear; Fs->draw_it=&DrawIt; I64 x,y,code,milk_cnt=0; CTask *snd=NULL; CQue head; QueInit(&head); C2DObjectRotate(cow_frog_milker,-pi/2); CCowTurd *cur; Bool milked_poophole=FALSE; F64 poop_hole_milk_time=0; while(TRUE) { code=ScanMsg(&x,&y); switch(code) { case MSG_MS_MOVE: milker_x=x,milker_y=y; break; case MSG_KEY_DOWN: if(x==CH_ESC) goto fin; break; case MSG_MS_L_DOWN: if(TaskValidate(snd)) Kill(snd); snd=ShitSound(33.,1000./33.,50,60,,1000); milker_sucking=TRUE; break; case MSG_MS_L_UP: Kill(snd); MusicSettingsRst; Snd; milker_sucking=FALSE; break; } if(milker_sucking) { if(!milked_poophole) if(70<=x<=210) if(25<=y<=150) { milked_poophole=TRUE; MilkExplosion(&head,x,y,$IB,"<5>",BI=5$); poop_hole_milk_time=tS; } if(!cow_frog.boob1_milk_time&&C2DObjectCollisionTest(cow_frog_milker,cow_frog.boob1->obj)) { cow_frog.boob1_milk_time=tS; milk_cnt++; x=cow_frog.boob1->obj->x; y=cow_frog.boob1->obj->y-70; MilkExplosion(&head,x,y,$IB,"<13>",BI=13$); } if(!cow_frog.boob2_milk_time&&C2DObjectCollisionTest(cow_frog_milker,cow_frog.boob2->obj)) { cow_frog.boob2_milk_time=tS; x=cow_frog.boob2->obj->x; y=cow_frog.boob2->obj->y-70; milk_cnt++; MilkExplosion(&head,x,y,$IB,"<13>",BI=13$); } if(!cow_frog.boob3_milk_time&&C2DObjectCollisionTest(cow_frog_milker,cow_frog.boob3->obj)) { cow_frog.boob3_milk_time=tS; milk_cnt++; x=cow_frog.boob3->obj->x; y=cow_frog.boob3->obj->y-70; MilkExplosion(&head,x,y,$IB,"<13>",BI=13$); } } Free(cow_frog.boob1->obj->user_data); Free(cow_frog.boob2->obj->user_data); Free(cow_frog.boob3->obj->user_data); if(cow_frog.boob1_milk_time) cow_frog.boob1->obj->user_data=cow_frog.boob1->obj->sprite=SpriteInterpolate(Clamp(tS-cow_frog.boob1_milk_time,0,1),$IB,"<10>",BI=10$,$IB,"<11>",BI=11$); if(cow_frog.boob2_milk_time) cow_frog.boob2->obj->user_data=cow_frog.boob2->obj->sprite=SpriteInterpolate(Clamp(tS-cow_frog.boob2_milk_time,0,1),$IB,"<10>",BI=10$,$IB,"<11>",BI=11$); if(cow_frog.boob3_milk_time) cow_frog.boob3->obj->user_data=cow_frog.boob3->obj->sprite=SpriteInterpolate(Clamp(tS-cow_frog.boob3_milk_time,0,1),$IB,"<10>",BI=10$,$IB,"<11>",BI=11$); for(cur=head.next;cur!=&head;) cur=ProcessCowTurd(cur); Refresh; if(milked_poophole) { milk_type=MILKT_SHIT; if(!QueCnt(&head)) break; } else if(milk_cnt>=3) { milk_type=MILKT_MILK; if(!QueCnt(&head)) break; } } fin: //TODO wait for empty more cleanyl while(QueCnt(&head)||milk_explosion_cnt) { for(cur=head.next;cur!=&head;) cur=ProcessCowTurd(cur); Refresh; } Kill(snd); MusicSettingsRst; Snd; Fs->draw_it=NULL; } Milk; // // Scene 3,Fill milk jug // //REPLACE CYAN with color $SP,"<14>",BI=14$ world=game.world=C2DWorldNew(YELLOW); CDC *NewFromSprite(U8 *spr) { I64 mnx,mxx,mny,mxy; SpriteExtents(spr,&mnx,&mxx,&mny,&mxy); CDC *empty=DCNew(mxx-mnx,mxy-mny); DCFill(empty,TRANSPARENT); Sprite3(empty,-mnx,-mny,0,spr); return empty; } CDC *empty_jug_dc=NewFromSprite($IB,"<14>",BI=14$); CDC *full_jug_dc=NewFromSprite($IB,"<14>",BI=14$); U0 DrawIt(CTask *t,CDC *dc) { I64 w; DrawWorld(t,world); w=full_jug_dc->width; GrBlot(world->scrn,GR_WIDTH/2-w/2,120,empty_jug_dc); GrBlot(dc,0,0,world->scrn); } U0 FillJugScene() { F64 fill_percent=0; F64 fill_time=(20.*50./1000.),start_time=tS; I64 last_y=full_jug_dc->height,to_y=0,wi=empty_jug_dc->width_internal; CCowTurd *cur; CQue head; CTask *snd; QueInit(&head); Fs->draw_it=&DrawIt; snd=ShitSound(33.,1000./15.,40,30,,1000); DCColorChg(empty_jug_dc,CYAN,TRANSPARENT); switch(milk_type) { case MILKT_MILK: MilkExplosion(&head,GR_WIDTH/2,-50,$IB,"<13>",BI=13$); DCColorChg(full_jug_dc,CYAN,WHITE); break; case MILKT_SHIT: DCColorChg(full_jug_dc,CYAN,BROWN); MilkExplosion(&head,GR_WIDTH/2,-50,$IB,"<5>",BI=5$); break; } while(fill_percent<1.) { fill_percent=(tS-start_time)/fill_time; to_y=empty_jug_dc->height-fill_percent*empty_jug_dc->height; to_y=ClampI64(to_y,0,full_jug_dc->height); //y grows down,but we want to "full-up" for(;last_y>=to_y;last_y--) { MemCpy(empty_jug_dc->body+wi*last_y,full_jug_dc->body+wi*last_y,wi); } for(cur=head.next;cur!=&head;) cur=ProcessCowTurd(cur); Refresh; } while(QueCnt(&head)) { for(cur=head.next;cur!=&head;) cur=ProcessCowTurd(cur); Refresh; } Kill(snd); Snd; Fs->draw_it=NULL; Refresh; } FillJugScene; DCDel(empty_jug_dc),DCDel(full_jug_dc); C2DWorldDel(game.world); //Drink scene //Fucking asshole milk drinker Normal $SP,"<15>",BI=15$ //Enraged fucking milk drinker $SP,"<16>",BI=16$ //Happy fuckin milk drinker $SP,"<17>",BI=17$ //Arm $SP,"<18>",BI=18$ game.world=C2DWorldNew(CYAN); CBone *arm_bone=NULL; U0 DrawIt(CTask *t,CDC *dc) { I64 w; if(arm_bone) BoneUpdate(arm_bone); DrawWorld(t,world); GrBlot(dc,0,0,world->scrn); } U0 DrinkScene() { #define DRINK_STATE_CARRY 1 //Carry the milk to the mouth #define DRINK_STATE_DRINK 2 //Drink the milk #define DRINK_STATE_SMILE 3 #define DRINK_STATE_FROWN 4 U8 *interp; I64 state=DRINK_STATE_CARRY; F64 state_time=tS; C2DObject *arm_obj=C2DObjectNewFromSprite($IB,"<18>",BI=18$,game.game_task); C2DObject *face_obj=C2DObjectNewFromSprite($IB,"<15>",BI=15$,game.game_task); AddObjectToWorld(face_obj,game.world); AddObjectToWorld(arm_obj,game.world); arm_bone=BoneNew(arm_obj); CDC *empty_jug_dc=NewFromSprite($IB,"<14>",BI=14$); CDC *full_jug_dc=NewFromSprite($IB,"<14>",BI=14$); CTask *snd_task=NULL; DCColorChg(empty_jug_dc,CYAN,TRANSPARENT); if(milk_type==MILKT_SHIT) DCColorChg(full_jug_dc,CYAN,BROWN); if(milk_type==MILKT_MILK) DCColorChg(full_jug_dc,CYAN,WHITE); C2DObject *jug_obj=C2DObjectNewFromDC(full_jug_dc); AddObjectToWorld(jug_obj,game.world); C2DObjectMoveCenter(jug_obj,full_jug_dc->width,full_jug_dc->height); C2DObjectScale(jug_obj,.5); CBone *jug_bone=BoneNew(jug_obj); jug_bone->rot=pi/2.; jug_bone->y=-(240-150); arm_bone->x=GR_WIDTH/2-200; arm_bone->y=GR_HEIGHT; face_obj->x=GR_WIDTH/2; face_obj->y=GR_HEIGHT; QueIns(jug_bone,&arm_bone->child_bones); Fs->draw_it=&DrawIt; DocClear;  WinMax; I64 last_y=full_jug_dc->height-1,to_y; while(TRUE) { switch(state) { case DRINK_STATE_CARRY: if(!snd_task) snd_task=Sweep(1000,30,50); arm_bone->rot=Clamp(tS-state_time,0,1)*pi/2-pi/2; if(tS-state_time>=1) { state=DRINK_STATE_DRINK; state_time=tS; snd_task=NULL; } break; case DRINK_STATE_DRINK: if(!snd_task) snd_task=Noise(750,20,30); if(tS-state_time>=.75) { state_time=tS; if(milk_type==MILKT_MILK) state=DRINK_STATE_SMILE; else state=DRINK_STATE_FROWN; } to_y=empty_jug_dc->height*(1-Clamp((tS-state_time)/.75,0,.99)); for(;last_y>to_y;last_y--) MemCpy( full_jug_dc->body+full_jug_dc->width_internal*last_y, empty_jug_dc->body+full_jug_dc->width_internal*last_y, full_jug_dc->width_internal ); C2DObjectSetGraphics(jug_obj,full_jug_dc); C2DObjectMoveCenter(jug_obj,full_jug_dc->width,full_jug_dc->height); last_y=to_y; break; start: Free(arm_obj->user_data); case DRINK_STATE_SMILE: face_obj->user_data=interp=SpriteInterpolate(Clamp(tS-state_time,0,1),$IB,"<15>",BI=15$,$IB,"<17>",BI=17$); break; case DRINK_STATE_FROWN: face_obj->user_data=interp=SpriteInterpolate(Clamp(tS-state_time,0,1),$IB,"<15>",BI=15$,$IB,"<16>",BI=16$); break; end: face_obj->sprite=interp; if(tS-state_time>=1.5) { state=0; } break; case 0: goto en; } Refresh; } en: Fs->draw_it=NULL; } DrinkScene;Ou]G,j f\rjm fh qFpYYFrH L=WVFg4qStBW  RRvwDC  UVf)*=O=(+9> %-># #, )RPQik@+!%|3v f_ 75 (   Z8I%#4Ou]H,j f\rjm fh qFpYYFrH L=WVFg4qStBW  RRvwDC  UVf)*=+=(+:H %-># #, )RPQik@+!%|3v f_ 75 (   Z8I%#Hh 9$nw@F;~Ew9wBm4o&y-j\  b8F/' R 7% 2O42G1LAY>P3`2`'R(]PH'5'9!" (h ; nw@F;~Ew9wBm4o&y-jR "X3"H  4E42;.@>M;D0T/T$F%QD<$5'; !"  "        IR`qb{N2}>dIM;(&KN/$I%9*(?b_^$d&oC\=G7@=DJ81dT=:F$ i U `Y    HX$wXD E>  : EPFl0g"V# X:<57+ X:^;j.V2H&J/D/:G>NCD%8*#-16 9 d46+ I2(2A*#Z$:;@3 b  [X+ '0m0|'z5.V(V 4+X1 S& N* 8[F: XN "*Wh3RY  #>RB#   1s )v0   LNrm4x6}VKYU;4 w6s T?PJ M9O,W  gc^ZV ^] Vb bQ ]_(n) ^1]M eM]?f7.{DO NOT MILKef0 L tX#9c}<zF[^bKg@RGA D8R $TIQVPB% g g/C+Pip WCow Frog MilkZZ  (<=P(P'= Q>1GSGH:BA$YZ  ,*$O.O/ P&&QRBGoAiAK# **}{(y*#include "../_2d.HC"; #include "Skeletal.HC"; #include "poop.HC"; #include "Speech.HC"; // // Part 1. Xi Jinping's Speech // Part 2. Qaddafi butt fucking // Part 2.5 Qaddafi Speech // Part 2.75 Qaddafi Turgasm // // Part 1,Political thriller // CTask *mem_task=Fs; WinMax; #define SHIT_PRIORITY 0 #define SHIT_GRAVITY 25 #define SHIT_MAX_YVELO -75 #define SHIT_MAX_XVELO 150 #define SHIT_X_DRAG .95 class CShart:CQue { C2DObject *obj; F64 x,y; F64 last_x,last_y; F64 x_velo,y_velo; }; CShart shits; QueInit(&shits); U0 ShartMove(CShart *s) { s->last_x=s->x; s->last_y=s->y; s->y_velo+=SHIT_GRAVITY; s->x_velo*=SHIT_X_DRAG; s->y+=s->y_velo; s->x+=s->x_velo; } U0 ShartNew(F64 x,F64 y) { CShart *s=CAlloc(sizeof CShart,mem_task); s->x_velo=(Rand-1+.5)*2*SHIT_MAX_XVELO; s->y_velo=Rand*SHIT_MAX_YVELO; s->x=x; s->y=y; QueIns(s,shits.last); } CTask *mem_task=Fs; CBone *TalkBoneNew(C2DWorld *w,U8 *elems,I64 mouth_y) { CDC *res,*res2; I64 min_x,max_x,min_y,max_y; SpriteExtents(elems,&min_x,&max_x,&min_y,&max_y); res=DCNew(max_x-min_x+1,max_y-min_y+1); DCFill(res,TRANSPARENT); Sprite3(res,-min_x,-min_y,0,elems); res2=DCNew(res->width,res->height-mouth_y); DCFill(res2,TRANSPARENT); GrBlot(res2,0,-mouth_y,res); res->height=mouth_y; C2DObject *top=C2DObjectNewFromDC(res,mem_task); C2DObject *bottom=C2DObjectNewFromDC(res2,mem_task); C2DObjectMoveCenter(bottom,res2->width/2,res2->height); C2DObjectMoveCenter(top,res->width/2,res->height); CBone *bbone=BoneNew(bottom,mem_task); CBone *tbone=BoneNew(top,mem_task); tbone->mode=BONE_M_NORMAL; QueIns(tbone,&bbone->child_bones); tbone->y=-(res2->height-1); AddObjectToWorld(top,w); AddObjectToWorld(bottom,w); DCDel(res),DCDel(res2); return bbone; } $SP,"<1>",BI=1$ //Xi Jin Ping body $SP,"<2>",BI=2$ //Libyan President $SP,"<3>",BI=3$ #define WHO_QADDAFI 1 #define WHO_POOH 2 class CSpeech:CQue { U8 *text; I64 x,y,px,py; }; CSpeech speech_head; C2DWorld *dialog_world=C2DWorldNew(YELLOW); C2DObject *pooh_body_obj=C2DObjectNewFromSprite($IB,"<2>",BI=2$,Fs); AddObjectToWorld(pooh_body_obj,dialog_world); CBone *QaddafiBone=TalkBoneNew(dialog_world,$IB,"<3>",BI=3$,386-35); CBone *PoohBone1=BoneNew(pooh_body_obj,Fs); CBone *PoohBone2=TalkBoneNew(dialog_world,$IB,"<1>",BI=1$,270-75); U0 PoliticalDraw(CTask *t,CDC *dc) { CShart *s,*next; for(s=shits.next;s!=&shits;s=next) { next=s->next; if(!s->obj) { s->obj=C2DObjectNewFromSprite($IB,"<4>",BI=4$,); AddObjectToWorld(s->obj,dialog_world); } ShartMove(s); s->obj->priority=200; C2DObjectMove(s->obj,s->x,s->y); C2DObjectRotate(s->obj,Arg(s->x_velo,s->y_velo)); if(s->y>GR_HEIGHT) { C2DObjectDel(s->obj); QueRem(s); Free(s); } } BoneUpdate(PoohBone1); BoneUpdate(QaddafiBone); CSpeech *head=&speech_head,*cur; DrawWorld(t,dialog_world); GrBlot(dc,0,0,dialog_world->scrn); for(cur=head->next;cur!=head;cur=cur->next) { SpeechBubblePointTo(dc,cur->text,cur->px,cur->py,cur->x,cur->y); } } #define TALKT_TALK 1 #define TALKT_SHART 2 class CTalkTask { CBone *head_bone; //See TalkBoneNew motherfucker F64 end_ts; I64 talk_type; U8 *text; I64 bx,by; }; U0 TalkTask(CTalkTask *tt) { CBone *top_bone=tt->head_bone->child_bones.next; CSpeech *sp=CAlloc(sizeof (CSpeech),mem_task); if(tt->text) { sp->text=tt->text; sp->x=tt->bx; sp->y=tt->by; QueIns(sp,&speech_head); } F64 orig_rot=top_bone->rot; F64 orig_x=top_bone->x,orig_y=top_bone->y; F64 snd_end_ts=0; Bool sharted=FALSE; CTask *snd; while(tt->end_ts>tS) { switch(tt->talk_type) { case TALKT_TALK: if(!snd_end_ts) { Noise(1000.*(tt->end_ts-tS)*.9,10,100); snd_end_ts=tt->end_ts; } if(Blink(3)) { top_bone->y=orig_y-65; } else { top_bone->y=orig_y; } break; case TALKT_SHART: if(!sharted) { if(snd_end_ts<=0) { ss: sharted=TRUE; ShitSound(1000./10.,1000/15.,17,27,,(tt->end_ts-tS)*.9*10); snd_end_ts=tS+1000./5.; } else if(snd_end_ts>=tS) { goto ss; } } top_bone->rot=(Rand-.5)*2*pi/4-pi/4; top_bone->x=(Rand-.5)*2*100+orig_x; top_bone->y=-Rand*100+orig_y; Sleep(10); break; } sp->px=top_bone->obj->x; sp->py=top_bone->obj->y; Refresh; } top_bone->rot=orig_rot; top_bone->x=orig_x; top_bone->y=orig_y; if(tt->text){ Free(tt->text); QueRem(sp); Free(sp); } Kill(snd); Snd; Free(tt); } CTask *Talk(CBone *head,I64 type=TALKT_TALK,U8 *text,I64 bx=GR_WIDTH/2,I64 by=GR_HEIGHT/2) { CTalkTask *tt=CAlloc(sizeof CTalkTask); tt->end_ts=tS+3; tt->talk_type=type; tt->bx=bx,tt->by=by; if(text) tt->text=StrNew(text,mem_task); else tt->text=NULL; tt->head_bone=head; Spawn(&TalkTask,tt,,,Fs); } U0 PoliticalThriller1() { I64 cnt; QueInit(&speech_head); QueIns(PoohBone2,&PoohBone1->child_bones); PoohBone2->mode=BONE_M_NORMAL; PoohBone2->x=0; PoohBone2->y=-200; PoohBone1->y=GR_HEIGHT; PoohBone1->x=330; Fs->draw_it=&PoliticalDraw; Talk(PoohBone2,TALKT_SHART,"Stick dat Nigger Dick\nIn my Pooh Hole",GR_WIDTH-100,GR_HEIGHT/2.5); cnt=20; while(--cnt) { Sleep(500*2/ToF64(cnt)); ShartNew(PoohBone1->x-100,PoohBone1->y-200); } Sleep(1000); } PoliticalThriller1; // // Part 2 sex scene // CTask *mem_task=Fs; //Shit $SP,"<4>",BI=4$ //Xi Jin Ping $SP,"<5>",BI=5$ //Oboma Scroutm 1 $SP,"<6>",BI=6$ //Oboma ballsack 2 $SP,"<7>",BI=7$ //Oboma Shlong $SP,"<8>",BI=8$ //Oboma left ass check //0123456789abcdef0123456789abcdef //-2 //-1 $SP,"<9>",BI=9$ //1 //2 //2 //3 //4 //5 //6 //7 //8 //9 //a //b //c //d //e //f //0 //1 //2 //3 //4 //5 //6 //7 //8 //9 //a //b //c //d //e //Oboma right Butt $SP,"<10>",BI=10$ //Oboma Ass center //0123456789abcdef0123456789abcdef0123456789abcdef $SP,"<11>",BI=11$ //1 //2 //3 //4 //5 //6 //7 //8 //9 //a //b //c //d //e //f //0 //1 //2 //3 //4 //5 //6 //7 //8 //9 //a //Nigger dick $SP,"<12>",BI=12$ F64 RandRange(F64 min,F64 max) { F64 r=Rand; return min+(max-min)*r; } C2DWorld *sex_scene=C2DWorldNew(YELLOW); Bool sex_scene_done=FALSE; class CObomaAss { #define OBOMA_STATE_PREPARE 0 #define OBOMA_STATE_FUCK 1 #define OBOMA_STATE_SHIT 2 #define OBOMA_STATE_EJACULATE 4 #define OBOMA_STATE_END 5 I64 state; F64 start_ts; CBone *left,*center,*right; CBone *sack; CBone *shlong; F64 sack_jiggle_ts; }; CObomaAss *ObomaAssNew() { CObomaAss *ret=CAlloc(sizeof CObomaAss,mem_task); C2DObject *oboma_ass_center=C2DObjectNewFromSprite($IB,"<11>",BI=11$,mem_task); C2DObject *oboma_ass_left=C2DObjectNewFromSprite($IB,"<9>",BI=9$,mem_task); C2DObject *oboma_ass_right=C2DObjectNewFromSprite($IB,"<10>",BI=10$,mem_task); C2DObject *oboma_sack=C2DObjectNewFromSprite($IB,"<6>",BI=6$,mem_task); C2DObject *oboma_shlong=C2DObjectNewFromSprite($IB,"<12>",BI=12$,mem_task); AddObjectToWorld(oboma_ass_left,sex_scene); AddObjectToWorld(oboma_ass_right,sex_scene); AddObjectToWorld(oboma_ass_center,sex_scene); AddObjectToWorld(oboma_sack,sex_scene); AddObjectToWorld(oboma_shlong,sex_scene); ret->left=BoneNew(oboma_ass_left,mem_task); ret->right=BoneNew(oboma_ass_right,mem_task); ret->center=BoneNew(oboma_ass_center,mem_task); ret->sack=BoneNew(oboma_sack,mem_task); ret->shlong=BoneNew(oboma_shlong,mem_task); QueIns(ret->left,&ret->center->child_bones); ret->left->y=0x2*8; ret->left->x=0x10*8; ret->left->mode=BONE_M_POINT_TO; ret->left->point_rot_off=pi+pi/2; QueIns(ret->right,&ret->center->child_bones); ret->right->y=0; ret->right->x=0x25*8; ret->right->mode=BONE_M_POINT_TO; ret->right->point_rot_off=-pi/2; QueIns(ret->sack,&ret->center->child_bones); ret->sack->x=0x1a*8; ret->sack->y=0x15*8; ret->sack_jiggle_ts=tS; ret->start_ts=tS; QueIns(ret->shlong,&ret->center->child_bones); ret->shlong->x=0x1a*8; ret->shlong->y=0x15*8; return ret; } CObomaAss *oboma=ObomaAssNew; U0 ObomaAnimate() { I64 cnt; U8 *interp; static Bool turdgasm=FALSE; F64 state_time=tS-oboma->start_ts; oboma->left->point_y=GR_HEIGHT*4.5; oboma->right->point_y=GR_HEIGHT*4.5; oboma->left->point_x=0; oboma->right->point_x=GR_WIDTH; switch(oboma->state) { case OBOMA_STATE_PREPARE: oboma->center->x=GR_WIDTH/2-150; oboma->center->y=GR_HEIGHT/2-100-2.5*(2.5-state_time)*200; if(state_time>=2.5) { oboma->state=OBOMA_STATE_FUCK; oboma->start_ts=tS; } break; case OBOMA_STATE_FUCK: oboma->center->x=GR_WIDTH/2-150; oboma->center->y=GR_HEIGHT/2-100+Sin((tS-oboma->start_ts)*pi*5)*120; static I64 swap=FALSE; if(swap!=Blink(15)) { swap=Blink(15); ShartNew(oboma->center->x+0x1a*8,oboma->center->y+0xf*8); ShitSound(1000./10,1000/15.,17,27); } if(state_time>=3.5) { oboma->state=OBOMA_STATE_EJACULATE; oboma->start_ts=tS; } break; case OBOMA_STATE_EJACULATE: if(state_time<1) { //Wait for suspense } else { //Turdgasm if(!turdgasm) { ShitSound(1000,1000/15.,17,27); for(cnt=0;cnt!=7;cnt++) { ShartNew(oboma->center->x+0x1a*8,oboma->center->y+0xf*8); } turdgasm=TRUE; } oboma->left->mode=BONE_M_NORMAL; oboma->right->mode=BONE_M_NORMAL; if(1) { oboma->left->rot=RandRange(-pi/4,pi/4); oboma->right->rot=RandRange(-pi/4,pi/4); oboma->shlong->rot=RandRange(-pi/4,pi/4); oboma->sack->rot=RandRange(-pi/4,pi/4); } } if(state_time>=3.5) { oboma->state=OBOMA_STATE_END; oboma->start_ts=tS; } break; case OBOMA_STATE_END: if(state_time>1) { sex_scene_done=TRUE; } } interp=SpriteInterpolate(.5+Sin(tS-oboma->sack_jiggle_ts)/2,$IB,"<6>",BI=6$,$IB,"<7>",BI=7$); Free(oboma->sack->obj->user_data); C2DObjectDel(oboma->sack->obj); oboma->sack->obj=C2DObjectNewFromSprite(interp,mem_task); oboma->sack->obj->user_data=interp; AddObjectToWorld(oboma->sack->obj,sex_scene); BoneUpdate(oboma->center); oboma->center->obj->priority=100; oboma->right->obj->priority=99; oboma->left->obj->priority=98; oboma->sack->obj->priority=97; oboma->shlong->obj->priority=96; } C2DObject *xi_jin_ping=C2DObjectNewFromSprite($IB,"<5>",BI=5$,mem_task); AddObjectToWorld(xi_jin_ping,sex_scene); xi_jin_ping->priority=-1; C2DObjectMove(xi_jin_ping,380,380); U0 FuckDrawIt(CTask *t,CDC *dc) { CShart *s,*next; ObomaAnimate; for(s=shits.next;s!=&shits;s=next) { next=s->next; if(!s->obj) { s->obj=C2DObjectNewFromSprite($IB,"<4>",BI=4$,mem_task); AddObjectToWorld(s->obj,sex_scene); } ShartMove(s); s->obj->priority=200; C2DObjectMove(s->obj,s->x,s->y); C2DObjectRotate(s->obj,Arg(s->x_velo,s->y_velo)); if(s->y>GR_HEIGHT) { C2DObjectDel(s->obj); QueRem(s); Free(s); } } DrawWorld(t,sex_scene); GrBlot(dc,0,0,sex_scene->scrn); } U0 Scene2() { Fs->draw_it=&FuckDrawIt; while(oboma->state!=OBOMA_STATE_EJACULATE) { Refresh; } Fs->draw_it=NULL; } Scene2; // // Scene 2.5 // U0 Scene2_5() { Fs->draw_it=&PoliticalDraw; QaddafiBone->x=GR_WIDTH/2; QaddafiBone->y=GR_HEIGHT; PoohBone1->x=100000; PoohBone1->y=100000; Talk(QaddafiBone,TALKT_TALK,"Bout 2 Bust Nigga",GR_WIDTH-200,GR_HEIGHT/2.5); Sleep(1000); } Scene2_5; // //Scene 2.75 // U0 Scene2_75() { Fs->draw_it=&FuckDrawIt; oboma->state=OBOMA_STATE_EJACULATE; oboma->start_ts=tS; while(oboma->state!=OBOMA_STATE_END) { Refresh; } Fs->draw_it=NULL; } Scene2_75;; Exit;  $Yu@8c5f?FFbkns9:$=(Ocg.eO7;= <a  $~a   : -To}^<W%|>jXK:+  + E )C 2 . *. 8 Iq]a!CYr?E8*  . c 0_ - 9 D D)*CD, ?+`Z L JG _4/?4O\kz i ynT j j l  "FD ? r9 p E[ q  q s  \ XG4]^mkiyvl >~3A{(G20^,.\  7Sd    +J     .2 "    >   0Q ] [ PgDVW WVn NYYZ `*h6i @kbcڹ w s? Y\[O=?AKg=5dj w  ZtgmxeH~+Wm0 :@V O 8V {wc:! wtN#u uo[QB0 Ev G,-tI #p^ dS QL| cy}nV- ^ UE 0 2=<(!2 !4-  X!^%6^6V! M{IAK ~{ |uP LI O 4wu wE1\3\ tl \t  qs  `s _jfS]n ` q  895 KK]0y&  & ,baWW;l| >aXvk f git d r { pI* ?s `vt,#include "../_2d.HC"; #include "Skeletal.HC"; #include "poop.HC"; #include "Speech.HC"; // // Part 1. Xi Jinping's Speech // Part 2. Qaddafi butt fucking // Part 2.5 Qaddafi Speech // Part 2.75 Qaddafi Turgasm // // Part 1,Political thriller // CTask *mem_task=Fs; WinMax; #define SHIT_PRIORITY 0 #define SHIT_GRAVITY 25 #define SHIT_MAX_YVELO -75 #define SHIT_MAX_XVELO 150 #define SHIT_X_DRAG .95 class CShart:CQue { C2DObject *obj; F64 x,y; F64 last_x,last_y; F64 x_velo,y_velo; }; CShart shits; QueInit(&shits); U0 ShartMove(CShart *s) { s->last_x=s->x; s->last_y=s->y; s->y_velo+=SHIT_GRAVITY; s->x_velo*=SHIT_X_DRAG; s->y+=s->y_velo; s->x+=s->x_velo; } U0 ShartNew(F64 x,F64 y) { CShart *s=CAlloc(sizeof CShart,mem_task); s->x_velo=(Rand-1+.5)*2*SHIT_MAX_XVELO; s->y_velo=Rand*SHIT_MAX_YVELO; s->x=x; s->y=y; QueIns(s,shits.last); } CTask *mem_task=Fs; CBone *TalkBoneNew(C2DWorld *w,U8 *elems,I64 mouth_y) { CDC *res,*res2; I64 min_x,max_x,min_y,max_y; SpriteExtents(elems,&min_x,&max_x,&min_y,&max_y); res=DCNew(max_x-min_x+1,max_y-min_y+1); DCFill(res,TRANSPARENT); Sprite3(res,-min_x,-min_y,0,elems); res2=DCNew(res->width,res->height-mouth_y); DCFill(res2,TRANSPARENT); GrBlot(res2,0,-mouth_y,res); res->height=mouth_y; C2DObject *top=C2DObjectNewFromDC(res,mem_task); C2DObject *bottom=C2DObjectNewFromDC(res2,mem_task); C2DObjectMoveCenter(bottom,res2->width/2,res2->height); C2DObjectMoveCenter(top,res->width/2,res->height); CBone *bbone=BoneNew(bottom,mem_task); CBone *tbone=BoneNew(top,mem_task); tbone->mode=BONE_M_NORMAL; QueIns(tbone,&bbone->child_bones); tbone->y=-(res2->height-1); AddObjectToWorld(top,w); AddObjectToWorld(bottom,w); DCDel(res),DCDel(res2); return bbone; } $SP,"<1>",BI=1$ //Xi Jin Ping body $SP,"<2>",BI=2$ //Libyan President $SP,"<3>",BI=3$ #define WHO_QADDAFI 1 #define WHO_POOH 2 class CSpeech:CQue { U8 *text; I64 x,y,px,py; }; CSpeech speech_head; C2DWorld *dialog_world=C2DWorldNew(YELLOW); C2DObject *pooh_body_obj=C2DObjectNewFromSprite($IB,"<2>",BI=2$,Fs); AddObjectToWorld(pooh_body_obj,dialog_world); CBone *QaddafiBone=TalkBoneNew(dialog_world,$IB,"<3>",BI=3$,386-35); CBone *PoohBone1=BoneNew(pooh_body_obj,Fs); CBone *PoohBone2=TalkBoneNew(dialog_world,$IB,"<1>",BI=1$,270-75); U0 PoliticalDraw(CTask *t,CDC *dc) { CShart *s,*next; for(s=shits.next;s!=&shits;s=next) { next=s->next; if(!s->obj) { s->obj=C2DObjectNewFromSprite($IB,"<4>",BI=4$,); AddObjectToWorld(s->obj,dialog_world); } ShartMove(s); s->obj->priority=200; C2DObjectMove(s->obj,s->x,s->y); C2DObjectRotate(s->obj,Arg(s->x_velo,s->y_velo)); if(s->y>GR_HEIGHT) { C2DObjectDel(s->obj); QueRem(s); Free(s); } } BoneUpdate(PoohBone1); BoneUpdate(QaddafiBone); CSpeech *head=&speech_head,*cur; DrawWorld(t,dialog_world); GrBlot(dc,0,0,dialog_world->scrn); for(cur=head->next;cur!=head;cur=cur->next) { SpeechBubblePointTo(dc,cur->text,cur->px,cur->py,cur->x,cur->y); } } #define TALKT_TALK 1 #define TALKT_SHART 2 class CTalkTask { CBone *head_bone; //See TalkBoneNew motherfucker F64 end_ts; I64 talk_type; U8 *text; I64 bx,by; }; U0 TalkTask(CTalkTask *tt) { CBone *top_bone=tt->head_bone->child_bones.next; CSpeech *sp=CAlloc(sizeof (CSpeech),mem_task); if(tt->text) { sp->text=tt->text; sp->x=tt->bx; sp->y=tt->by; QueIns(sp,&speech_head); } F64 orig_rot=top_bone->rot; F64 orig_x=top_bone->x,orig_y=top_bone->y; F64 snd_end_ts=0; Bool sharted=FALSE; CTask *snd; while(tt->end_ts>tS) { switch(tt->talk_type) { case TALKT_TALK: if(!snd_end_ts) { snd=Noise(1000.*(tt->end_ts-tS)*.9,10,100); snd_end_ts=tt->end_ts; } if(Blink(3)) { top_bone->y=orig_y-65; } else { top_bone->y=orig_y; } break; case TALKT_SHART: if(!sharted) { if(snd_end_ts<=0) { ss: sharted=TRUE; snd=ShitSound(1000./10.,1000/15.,17,27,,(tt->end_ts-tS)*.9*10); snd_end_ts=tS+1000./5.; } else if(snd_end_ts>=tS) { goto ss; } } top_bone->rot=(Rand-.5)*2*pi/4-pi/4; top_bone->x=(Rand-.5)*2*100+orig_x; top_bone->y=-Rand*100+orig_y; Sleep(10); break; } sp->px=top_bone->obj->x; sp->py=top_bone->obj->y; Refresh; } top_bone->rot=orig_rot; top_bone->x=orig_x; top_bone->y=orig_y; if(tt->text){ Free(tt->text); QueRem(sp); Free(sp); } Kill(snd); Snd; Free(tt); } CTask *Talk(CBone *head,I64 type=TALKT_TALK,U8 *text,I64 bx=GR_WIDTH/2,I64 by=GR_HEIGHT/2) { CTalkTask *tt=CAlloc(sizeof CTalkTask); tt->end_ts=tS+3; tt->talk_type=type; tt->bx=bx,tt->by=by; if(text) tt->text=StrNew(text,mem_task); else tt->text=NULL; tt->head_bone=head; Spawn(&TalkTask,tt,,,Fs); } U0 PoliticalThriller1() { I64 cnt; QueInit(&speech_head); QueIns(PoohBone2,&PoohBone1->child_bones); PoohBone2->mode=BONE_M_NORMAL; PoohBone2->x=0; PoohBone2->y=-200; PoohBone1->y=GR_HEIGHT; PoohBone1->x=330; Fs->draw_it=&PoliticalDraw; Talk(PoohBone2,TALKT_SHART,"Stick dat Nigger Dick\nIn my Pooh Hole",GR_WIDTH-100,GR_HEIGHT/2.5); cnt=20; while(--cnt) { Sleep(500*2/ToF64(cnt)); ShartNew(PoohBone1->x-100,PoohBone1->y-200); } Sleep(1000); } PoliticalThriller1; // // Part 2 sex scene // CTask *mem_task=Fs; //Shit $SP,"<4>",BI=4$ //Xi Jin Ping $SP,"<5>",BI=5$ //Oboma Scroutm 1 $SP,"<6>",BI=6$ //Oboma ballsack 2 $SP,"<7>",BI=7$ //Oboma Shlong $SP,"<8>",BI=8$ //Oboma left ass check //0123456789abcdef0123456789abcdef //-2 //-1 $SP,"<9>",BI=9$ //1 //2 //2 //3 //4 //5 //6 //7 //8 //9 //a //b //c //d //e //f //0 //1 //2 //3 //4 //5 //6 //7 //8 //9 //a //b //c //d //e //Oboma right Butt $SP,"<10>",BI=10$ //Oboma Ass center //0123456789abcdef0123456789abcdef0123456789abcdef $SP,"<11>",BI=11$ //1 //2 //3 //4 //5 //6 //7 //8 //9 //a //b //c //d //e //f //0 //1 //2 //3 //4 //5 //6 //7 //8 //9 //a //Nigger dick $SP,"<12>",BI=12$ F64 RandRange(F64 min,F64 max) { F64 r=Rand; return min+(max-min)*r; } C2DWorld *sex_scene=C2DWorldNew(YELLOW); Bool sex_scene_done=FALSE; class CObomaAss { #define OBOMA_STATE_PREPARE 0 #define OBOMA_STATE_FUCK 1 #define OBOMA_STATE_SHIT 2 #define OBOMA_STATE_EJACULATE 4 #define OBOMA_STATE_END 5 I64 state; F64 start_ts; CBone *left,*center,*right; CBone *sack; CBone *shlong; F64 sack_jiggle_ts; }; CObomaAss *ObomaAssNew() { CObomaAss *ret=CAlloc(sizeof CObomaAss,mem_task); C2DObject *oboma_ass_center=C2DObjectNewFromSprite($IB,"<11>",BI=11$,mem_task); C2DObject *oboma_ass_left=C2DObjectNewFromSprite($IB,"<9>",BI=9$,mem_task); C2DObject *oboma_ass_right=C2DObjectNewFromSprite($IB,"<10>",BI=10$,mem_task); C2DObject *oboma_sack=C2DObjectNewFromSprite($IB,"<6>",BI=6$,mem_task); C2DObject *oboma_shlong=C2DObjectNewFromSprite($IB,"<12>",BI=12$,mem_task); AddObjectToWorld(oboma_ass_left,sex_scene); AddObjectToWorld(oboma_ass_right,sex_scene); AddObjectToWorld(oboma_ass_center,sex_scene); AddObjectToWorld(oboma_sack,sex_scene); AddObjectToWorld(oboma_shlong,sex_scene); ret->left=BoneNew(oboma_ass_left,mem_task); ret->right=BoneNew(oboma_ass_right,mem_task); ret->center=BoneNew(oboma_ass_center,mem_task); ret->sack=BoneNew(oboma_sack,mem_task); ret->shlong=BoneNew(oboma_shlong,mem_task); QueIns(ret->left,&ret->center->child_bones); ret->left->y=0x2*8; ret->left->x=0x10*8; ret->left->mode=BONE_M_POINT_TO; ret->left->point_rot_off=pi+pi/2; QueIns(ret->right,&ret->center->child_bones); ret->right->y=0; ret->right->x=0x25*8; ret->right->mode=BONE_M_POINT_TO; ret->right->point_rot_off=-pi/2; QueIns(ret->sack,&ret->center->child_bones); ret->sack->x=0x1a*8; ret->sack->y=0x15*8; ret->sack_jiggle_ts=tS; ret->start_ts=tS; QueIns(ret->shlong,&ret->center->child_bones); ret->shlong->x=0x1a*8; ret->shlong->y=0x15*8; return ret; } CObomaAss *oboma=ObomaAssNew; U0 ObomaAnimate() { I64 cnt; U8 *interp; static Bool turdgasm=FALSE; F64 state_time=tS-oboma->start_ts; oboma->left->point_y=GR_HEIGHT*4.5; oboma->right->point_y=GR_HEIGHT*4.5; oboma->left->point_x=0; oboma->right->point_x=GR_WIDTH; switch(oboma->state) { case OBOMA_STATE_PREPARE: oboma->center->x=GR_WIDTH/2-150; oboma->center->y=GR_HEIGHT/2-100-2.5*(2.5-state_time)*200; if(state_time>=2.5) { oboma->state=OBOMA_STATE_FUCK; oboma->start_ts=tS; } break; case OBOMA_STATE_FUCK: oboma->center->x=GR_WIDTH/2-150; oboma->center->y=GR_HEIGHT/2-100+Sin((tS-oboma->start_ts)*pi*5)*120; static I64 swap=FALSE; if(swap!=Blink(15)) { swap=Blink(15); ShartNew(oboma->center->x+0x1a*8,oboma->center->y+0xf*8); ShitSound(1000./10,1000/15.,17,27); } if(state_time>=3.5) { oboma->state=OBOMA_STATE_EJACULATE; oboma->start_ts=tS; } break; case OBOMA_STATE_EJACULATE: if(state_time<1) { //Wait for suspense } else { //Turdgasm if(!turdgasm) { for(cnt=0;cnt!=7;cnt++) { ShartNew(oboma->center->x+0x1a*8,oboma->center->y+0xf*8); } ShitSound(1000,1000/15.,17,27); turdgasm=TRUE; } oboma->left->mode=BONE_M_NORMAL; oboma->right->mode=BONE_M_NORMAL; if(1) { oboma->left->rot=RandRange(-pi/4,pi/4); oboma->right->rot=RandRange(-pi/4,pi/4); oboma->shlong->rot=RandRange(-pi/4,pi/4); oboma->sack->rot=RandRange(-pi/4,pi/4); } } if(state_time>=3.5) { oboma->state=OBOMA_STATE_END; oboma->start_ts=tS; } break; case OBOMA_STATE_END: if(state_time>1) { sex_scene_done=TRUE; } } interp=SpriteInterpolate(.5+Sin(tS-oboma->sack_jiggle_ts)/2,$IB,"<6>",BI=6$,$IB,"<7>",BI=7$); Free(oboma->sack->obj->user_data); C2DObjectDel(oboma->sack->obj); oboma->sack->obj=C2DObjectNewFromSprite(interp,mem_task); oboma->sack->obj->user_data=interp; AddObjectToWorld(oboma->sack->obj,sex_scene); BoneUpdate(oboma->center); oboma->center->obj->priority=100; oboma->right->obj->priority=99; oboma->left->obj->priority=98; oboma->sack->obj->priority=97; oboma->shlong->obj->priority=96; } C2DObject *xi_jin_ping=C2DObjectNewFromSprite($IB,"<5>",BI=5$,mem_task); AddObjectToWorld(xi_jin_ping,sex_scene); xi_jin_ping->priority=-1; C2DObjectMove(xi_jin_ping,380,380); U0 FuckDrawIt(CTask *t,CDC *dc) { CShart *s,*next; ObomaAnimate; for(s=shits.next;s!=&shits;s=next) { next=s->next; if(!s->obj) { s->obj=C2DObjectNewFromSprite($IB,"<4>",BI=4$,mem_task); AddObjectToWorld(s->obj,sex_scene); } ShartMove(s); s->obj->priority=200; C2DObjectMove(s->obj,s->x,s->y); C2DObjectRotate(s->obj,Arg(s->x_velo,s->y_velo)); if(s->y>GR_HEIGHT) { C2DObjectDel(s->obj); QueRem(s); Free(s); } } DrawWorld(t,sex_scene); GrBlot(dc,0,0,sex_scene->scrn); } U0 Scene2() { Fs->draw_it=&FuckDrawIt; while(oboma->state!=OBOMA_STATE_EJACULATE) { Refresh; } Fs->draw_it=NULL; } Scene2; // // Scene 2.5 // U0 Scene2_5() { Fs->draw_it=&PoliticalDraw; QaddafiBone->x=GR_WIDTH/2-100; QaddafiBone->y=GR_HEIGHT; PoohBone1->x=100000; PoohBone1->y=100000; Talk(QaddafiBone,TALKT_TALK,"Bout 2 Bust Nigga",GR_WIDTH-200,GR_HEIGHT/2.5); Sleep(1500); } Scene2_5; // //Scene 2.75 // U0 Scene2_75() { Snd; Fs->draw_it=&FuckDrawIt; oboma->state=OBOMA_STATE_EJACULATE; oboma->start_ts=tS; while(oboma->state!=OBOMA_STATE_END) { Refresh; } Fs->draw_it=NULL; } Scene2_75;; Exit;2H                                                                                 : -To}^<W%|>jXK:+  + E )C 2 . *. 8 Iq]a!CYr?E8*  . c 0_ - 9 Dگ'   " !F [                                                                 S<C  +J    * z                          /Q                                                  "                                                                                                                     #define SCENE_OBOMA_SEX 1 #define SCENE_ABORTION 2 U0 PlayScene(I64 scene_num=-1) { CTask *st; U8 *file; switch(scene_num) { case SCENE_OBOMA_SEX: file=FileNameAbs("ObamaSexScene.HC"); st=User("ExeFile2(\"%q\");;\n",file); Free(file); DeathWait(st); break; case SCENE_ABORTION: file=FileNameAbs("frogs.HC"); st=User("ExeFile2(\"%q\");;Game(&AbortionSceneLevel);;\n",file); Free(file); DeathWait(st); break; } } PlayScene(1);#ifndef SKELETAL #define SKELETAL #include "../_2d.HC"; class CBone:CQue { C2DObject *obj; //Bone takes rotation from rot #define BONE_M_NORMAL 0 //Bone points to point_x,point_y motherfucker(point_rot_off is added to rot) #define BONE_M_POINT_TO 1 I64 mode; #define BONE_F_FLIP 1 I64 flags; F64 x,y,length; F64 point_x,point_y,point_rot_off; F64 rot; CQue child_bones; }; CBone *BoneNew(C2DObject *obj,CTask *mem_task=NULL) { CBone *b=CAlloc(sizeof CBone,mem_task); b->obj=obj; QueInit(&b->child_bones); return b; } //Recursive U0 BoneSetFlip(CBone *bone,Bool on=TRUE) { if(on) bone->flags|=BONE_F_FLIP,bone->obj->flipped=TRUE; else bone->flags&=~BONE_F_FLIP,bone->obj->flipped=FALSE; CBone *head=&bone->child_bones,*cur; for(cur=head->next;cur!=head;cur=cur->next) BoneSetFlip(cur,on); } F64 FlipAngle(F64 a) { return (pi-a)+pi; } U0 BoneUpdate(CBone *bone,CBone *parent=NULL) { CBone *head,*cur; F64 dist,ang,flip=1; if(parent&&parent->flags&BONE_F_FLIP) flip=-1; if(!parent) { bone->obj->x=bone->x; bone->obj->y=bone->y; bone->obj->rot=bone->rot; bone->obj->flipped=!!(bone->flags&BONE_F_FLIP); } else { switch(bone->mode) { start: bone->obj->x=parent->obj->x; bone->obj->y=parent->obj->y; dist=Sqrt(Sqr(bone->x)+Sqr(bone->y)); ang=Arg(flip*bone->x,bone->y); bone->obj->x+=dist*Cos(parent->obj->rot+ang); bone->obj->y+=dist*Sin(parent->obj->rot+ang); case BONE_M_NORMAL: if(!(bone->flags&BONE_F_FLIP)) bone->obj->rot=bone->rot+parent->obj->rot; else bone->obj->rot=FlipAngle(bone->rot)+parent->obj->rot; break; case BONE_M_POINT_TO: if(!(bone->flags&BONE_F_FLIP)) bone->obj->rot=Arg(bone->point_x-bone->obj->x,bone->point_y-bone->obj->y)+bone->point_rot_off; else bone->obj->rot=FlipAngle(Arg(-(bone->point_x-bone->obj->x),bone->point_y-bone->obj->y)+bone->point_rot_off); break; end:; } } head=&bone->child_bones; for(cur=head->next;cur!=head;cur=cur->next) { BoneUpdate(cur,bone); } } /*C2DWorld *w=C2DWorldNew(BLACK); CDC*rect1=DCNew(200,50); CDC*rect2=DCNew(100,50); DCFill(rect1,YELLOW); DCFill(rect2,CYAN); CDC*sq=DCNew(50,50); DCFill(sq,RED); C2DObject *arm=C2DObjectNewFromDC(rect1); C2DObject *arm2=C2DObjectNewFromDC(rect2); C2DObject *hand=C2DObjectNewFromDC(sq); C2DObjectMoveCenter(arm,0,25); C2DObjectMoveCenter(arm2,0,25); C2DObjectMoveCenter(hand,0,0); CBone *arm_bone=BoneNew(arm); CBone *arm_bone2=BoneNew(arm2); arm_bone->x=0,arm_bone->y=0; arm_bone2->x=200,arm_bone2->y=25; CBone *hand_bone=BoneNew(hand); hand_bone->x=100; hand_bone->y=0; QueIns(arm_bone2,&arm_bone->child_bones); QueIns(hand_bone,&arm_bone2->child_bones); AddObjectToWorld(arm,w); AddObjectToWorld(arm2,w); AddObjectToWorld(hand,w); U0 DrawIt(CTask *t,CDC *dc) { arm_bone->x=GR_WIDTH/2; arm_bone->y=GR_HEIGHT/2; arm_bone->rot=tS; arm_bone2->rot=tS*3; arm_bone2->mode=BONE_M_POINT_TO; arm_bone->point_x=0; arm_bone->point_y=0; BoneUpdate(arm_bone); DrawWorld(t,w); GrBlot(dc,0,0,w->scrn); } Fs->draw_it=&DrawIt; while(1) { BoneSetFlip(arm_bone,Blink); Refresh; }*/ #endif#ifndef SPEECH_H #define SPEECH_H U0 FitRectInEllipse(I64 x,I64 y,I64 *rw,I64 *rh,I64 margin=25) { I64 min_w=x/2,min_h=y/2; F64 b=min_h+margin,angle=Arg(min_w,-margin),dist1=Sqrt(Sqr(min_w)+Sqr(margin)); F64 dist2=Abs(b/Tan(angle)); if(rw) *rw=dist2*2; if(rh) *rh=b*2; } CDC *SpeechBubble0(U8 *text,I64 color=CYAN,I64 margin=25) { text=StrNew(text); U8 *ln; CDC *dc; I64 width=0,height=8*(1+StrOcc(text,'\n')); I64 lines=height/8,line=0,ow,oh; while(StrOcc(text,'\n')) *StrLastOcc(text,"\n")=0; line=0; while(linecolor=BLACK; dc->thick=4; GrEllipse3(dc,4+width/2,4+height/2,0,width/2,height/2); dc->color=WHITE; GrFloodFill(dc,4+width/2,4+height/2); for(line=0;line!=lines;line++) { dc->color=color; ln=LstSub(line,text); if(ln) GrPrint(dc,4+width/2-4*StrLen(ln),4+8*line+height/2-4*lines,"%s",ln); } Free(text); return dc; } //dx,dy is the stat of the arrow, //cx,cy is the speech bubble positon U0 SpeechBubblePointTo(CDC *dc,U8 *text,I64 dx,I64 dy,I64 cx,I64 cy, I64 color=CYAN,I64 margin=25) { dc->color=WHITE; CDC *speech_bubble=SpeechBubble0(text,color,margin); CD3I32 points[3]; F64 angle,gap_angle; F64 dist; //Ensure speech bubble is in dc's bounds if(cx-speech_bubble->width/2<0) cx=speech_bubble->width/2; if(cx+speech_bubble->width/2>dc->width) cx=dc->width-speech_bubble->width/2; if(cy-speech_bubble->height/2<0) cy=0; if(cy+speech_bubble->height/2>dc->height) cy=dc->height-speech_bubble->height/2; angle=Arg(cx-dx,cy-dy); dist=Sqrt(Sqr(dx-cx)+Sqr(dy-cy)); MemSet(&points,0,sizeof(CD3I32)*3); gap_angle=ATan(15./dist); points[0].x=dx; points[0].y=dy; points[1].x=dx+dist*Cos(angle-gap_angle); points[1].y=dy+dist*Sin(angle-gap_angle); points[2].x=dx+dist*Cos(angle+gap_angle); points[2].y=dy+dist*Sin(angle+gap_angle); GrFillTri0(dc,&points[0],&points[1],&points[2]); dc->thick=4; dc->color=BLACK; GrLine3(dc,dx,dy,0,points[1].x,points[1].y,0); GrLine3(dc,dx,dy,0,points[2].x,points[2].y,0); GrBlot(dc,cx-speech_bubble->width/2,cy-speech_bubble->height/2,speech_bubble); DCDel(speech_bubble); } #endif [RBP+8] <<= The Return address [RBP] <<= The old RBP CALL_TOS_0_ZERO_BP [RBP+8] <<= //NULL enter function [RBP] <<= 0 //Signifies end of stack //Check the [RBP+8] Caller(0) == NULL#define LOBBY_CLIENT #include "frogs"; #exe {Cd(__DIR__);;};; #include "../_2d.HC"; #include "Speech.HC"; #define REG_SCORE "nroot/frogs/score" RegDft(REG_SCORE,"I64 high_score=0;;"); RegExe(REG_SCORE); #include "../UI.HC"; #include "../Eliza/Eliza.HC"; #include "../Server.HC" #include "lobby"; #define PREC1 precision 1 extern class CFrog; //FrogHead open $SP,"<1>",BI=1$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *frog_head_open=C2DObjectNewFromSprite($IB,"<1>",BI=1$); //Frog Head dead $SP,"<2>",BI=2$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *frog_head_dead=C2DObjectNewFromSprite($IB,"<2>",BI=2$); //FrogHead close $SP,"<3>",BI=3$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *frog_head_close=C2DObjectNewFromSprite($IB,"<3>",BI=3$); //Frog jump $SP,"<4>",BI=4$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *frog_jump=C2DObjectNewFromSprite($IB,"<4>",BI=4$); //Frog sit $SP,"<5>",BI=5$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *frog_sit=C2DObjectNewFromSprite($IB,"<5>",BI=5$); //Fly $SP,"<6>",BI=6$ C2DObject *fly1=C2DObjectNewFromSprite($IB,"<6>",BI=6$); //Fly2 $SP,"<7>",BI=7$ C2DObject *fly2=C2DObjectNewFromSprite($IB,"<7>",BI=7$); //Wasp1(6,9) $SP,"<8>",BI=8$ //123456789abcdef //1 //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *wasp1=C2DObjectNewFromSprite($IB,"<8>",BI=8$); //Wasp2() $SP,"<9>",BI=9$ //123456789abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *wasp2=C2DObjectNewFromSprite($IB,"<9>",BI=9$); //Background water $SP,"<10>",BI=10$ //1 //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *water=C2DObjectNewFromSprite($IB,"<10>",BI=10$); //Lily pad $SP,"<11>",BI=11$ //1 //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *lily_pad=C2DObjectNewFromSprite($IB,"<11>",BI=11$); $SP,"<12>",BI=12$ // // // // $SP,"<13>",BI=13$ // // // // $SP,"<14>",BI=14$ class CShitSound2 { I64 duration,freq,lo,hi; F64 dampening; }; CTask *ShitSoundTask2(CShitSound2 *s) { music.mute++; F64 t=tS,e=t+ToF64(s->duration)/1000,cur=t; F64 next_dec=1./(s->freq)+t; for(;cur=next_dec) { next_dec=1./(s->freq)+cur; s->hi*=s->dampening; s->lo*=s->dampening; } Snd(s->lo+(s->hi-s->lo)*Caw(cur-t,1./s->freq)); Sleep(1); } Snd; music.mute--; } CTask *ShitSound2(I64 duration,I64 freq=20,I64 lo=47,I64 hi=27,F64 dampening=.9) { CShitSound2 *s=AMAlloc(sizeof CShitSound2); s->duration=duration,s->freq=freq,s->lo=lo,s->hi=hi; s->dampening=dampening; return Spawn(&ShitSoundTask2,s); } #define FLY_PATTERN_SINE 0 //Bezier #define FLY_PATTERN_BEZIER 1 //Line #define FLY_PATTERN_ZIP 2 //"Random" #define FLY_PATTERN_RANDOM 3 //CWasp Attacks a frog ->target //Wasps will spawn not angry,but when provoked will attack #define FLY_PATTERN_ATTACK 4 #define FLY_SINE_DIVIDE 60. #define FLY_ANIMATION_FREQ 10 // // CFly can refer to a wasp or a fly.(they both fly around) // fly_type will be FLYT_WASP for a wasp,and will use class CWasp(which has // type CWasp) class CFly:CServerThing { U8 *destroy dft "FlyDel"; C2DObject *body; #define FLYT_FLY 0 #define FLYT_WASP 1 I64 fly_type; F64 old_x PREC1,old_y PREC1; U0 pattern_info_start PREC1; F64 x PREC1,y PREC1,spawn_ts PREC1; //Animation cycle is a Sin and goes from 0 to 2*pi F64 spawn_x PREC1,spawn_y PREC1,animation_cycle PREC1; F64 origin_x PREC1,origin_y PREC1; //For Bezier F64 btarget_x PREC1,btarget_y PREC1; F64 end_x PREC1,end_y PREC1; F64 start_ts,sine_amplitude PREC1,speed; I64 pattern; I64 actions_until_leave; I64 actions_cnt; Bool done,pad[7]; }; class CWasp:CFly{ I64 state; CFrog *target swizzle; Bool is_angry,pad[7]; }; I64 GROUND_POSITION=GR_HEIGHT-8*7; #define TURD_CNT 64 #define TURD_GRAVITY 35 #define TURD_MELT_SPEED 3 class CTurd:CQue { C2DObject *turdg; F64 start_x PREC1,start_y PREC1,start_ts; F64 melt_percent; F64 xvelo PREC1,yvelo PREC1,start_angle; #define TURDS_PROJECTILE 1 //Turds will "melt" once the side of the arena #define TURDS_MELT 2 //Turd on the ground will sit until someone steps on them #define TURDS_GROUND 3 #define TURDS_STEPPED_ON 4 #define TURDS_DONE 5 I64 state; }; //All are F64 unless otherwise noted(Use FrogMovieMake to make // a movie and assign it to frog->user_data) #define FROG_MOVIE_JUMP 1 //Towards (x,y,velo) //Velo can be 0 for dft #define FROG_MOVIE_LOOK 2 //Towards (x,y,time) #define FROG_MOVIE_EAT 3 //Towards (x,y) #define FROG_MOVIE_STICK_OBJECT_TO_TONGUE 4 //At (x,y,C2DObject*) #define FROG_MOVIE_SHIT 5 //(Turds,duration) #define FROG_MOVIE_SLEEP 6 //Will sleep for (F64 seconds) #define FROG_MOVIE_DONE 7 //Will set ai_state[0] to FROG_MOVIE_DONE extern I64 *FrogMovieMake(...); extern U0 FrogAIMovieScene(CFrog *frog); extern U0 GameClear(); extern U0 TurdProjectileMove(CTurd *p); extern U0 ContinueAssBlast(CFrog *f); extern U0 InitAssBlastForFrog(CFrog *f,I64 turds,Bool propel=TRUE); extern U0 AssBlastFinish(CFrog *); extern U0 FrogSaySomethingToServer(CFrog *f,U8 *message); U0 TurdProjectileDel(CTurd *p) { QueRem(p); if(p->turdg) C2DObjectDel(p->turdg); Free(p); } class CAssBlast { F64 freq,duration,start_ts,next_turd_ts; CQue turds; Bool propel_into_air,pad[7]; }; #define FROG_SHIT_VELOCITY 100 #define FROG_JUMP_VELOCITY 100 #define FROG_GRAVITY 35 #define FROG_DRAW_PRIORITY 3 #define FLY_DRAW_PRIORITY 128 #define TURD_DRAW_PRIORITY 1000 #define FROGF_PLAYER (1<<0) #define FROGF_CPU (1<<1) #define FROGF_MOUTH_OPEN (1<<2) #define FROGF_SITTING (1<<3) #define FROGF_DEAD (1<<4) #define FROGF_SHIT_FEET (1<<5) #define FROGF_SHITTING (1<<6) //This will cause the frogs tongue to go backwards #define FROGF_OBJECT_ON_TONGUE (1<<7) #define FROGF_SEMENMAX (1<<8) #define FROGF_LEAVE_STAGE (1<<10) //Will cause the frog to be a girlfreind frog(will benefit FROGF_SEMENMAX frog) #define FROGF_GIRLFREIND (1<<11) #define FROG_TONGUE_LENGTH 350 #define FROG_TONGUE_MIN_LENGTH 30 F64 FROG_TONGUE_DURATION=.300; #define FROG_DEATH_TIME 2 #define MAX_FROGS 8 class CFrog:CServerThing { U8 *constructor dft "FrogConstructor"; U8 *destroy dft "FrogDel"; F64 x,y; F64 jump_start_x PREC1,jump_start_y PREC1,jump_start_angle; F64 looking_at_x PREC1,looking_at_y PREC1,jump_start_ts; F64 yvelo,xvelo; //Tongue cycle is like a sine wave F64 tongue_length PREC1,tongue_start_ts; CFrog *boyfriend_frog swizzle; I64 id2; I64 fly_count,flies_since_last_shit; I64 flags; I64 priority,color,lives; //In our game,if we hit a frog in the air,we only hit once to //avoid infintiy bouncy frogs I64 hit_vector; C2DObject *head,*body,*tongue; //AI Aritifcial interlegnce,what controls the computer frogs U8 ai[32]; I64 user_data; I64 user_data2; F64 ai_param1; F64 ai_param2; F64 ai_param3; F64 ai_param4; F64 ai_param5; F64 ai_param6; F64 ai_state[16]; //Once a frog dies,it looses a life then it times out until death_penalty_wait_until F64 death_penalty_wait_until; //This is used for when you hit another frog,It will wait //for the collision to end before bouncing off the other frog again I64 hit_bitmap[1+MAX_FROGS/64]; C2DObject *object_on_tongue; F64 shit_feet_time; CAssBlast ass_blast; U8 *speech_text; F64 speech_end_ts,power_up_end_ts; //Optional //Used for the graphics of the frog C2DObject *reference_sit; C2DObject *reference_jump; C2DObject *reference_head_open; C2DObject *reference_head_close; C2DObject *reference_head_dead; CEliza *chat_bot_eliza; CTask *chat_bot_task; U8 name[32]; }; extern I64 FrogCnt(); extern CFrog *FrogN(I64 n); CFrog *GetPlayerFrog(CServer *s) { U8 *name=UDPAddrToStr(CurrentClient->to),*str; I64 id=FramePtr(str=MStrPrint("PLAYER_FROG:%s",name)); Free(name),Free(str); CFrog *f; if(f=ServerId2Ptr(s,id)) if(!StrCmp(f->class_name,"CFrog")) return f; return NULL; } U0 FrogDel(CFrog *frog) { AssBlastFinish(frog); if(frog->head) C2DObjectDel(frog->head); if(frog->tongue) C2DObjectDel(frog->tongue); if(frog->body) C2DObjectDel(frog->body); if(frog->chat_bot_task) Kill(frog->chat_bot_task); Free(frog); } class CGame { F64 day_start; CServer *server; CTask *game_task,*sound_task,*day_task,*shit_sound_task; U0 (*level_task)(I64); CFrog *player; C2DObject*sun,*moon; C2DWorld *world; I64 game_over,ms_x,ms_y; CBGR48 palette[16]; CUIChatLog *chat_log; CUITextBar *chat_bar; CQue ui_root; Bool done,chat_bar_active; } game; MemSet(&game,0,sizeof(CGame)); //Use this in Fs->task_end_cb U0 GameDel() { CUIElem *e,*head=&game.ui_root,*next; ServerDel(game.server); for(e=head->next;e!=head;e=next) { next=e->next; UIKillElem(e); } Kill(game.game_task,FALSE); Kill(game.day_task,FALSE); Kill(game.sound_task,FALSE); Kill(game.shit_sound_task,FALSE); if(game.sun) C2DObjectDel(game.sun); if(game.moon) C2DObjectDel(game.moon); MemSet(&game,0,sizeof(CGame)); Exit; } //Moves out of way of the mouse cursor U0 UpdateUIChatLogGr() { I64 w=GR_WIDTH/2; if(game.ms_xx=game.game_task->pix_width-w-4; game.chat_bar->x=game.game_task->pix_width-w; game.chat_log->y=0; } else { game.chat_log->x=4; game.chat_bar->x=0; game.chat_log->y=0; } game.chat_bar->y=game.chat_log->y+game.chat_log->sz_y+4; if(game.chat_bar_active) { game.chat_bar->fg_color=CYAN; game.chat_bar->bg_color=WHITE; game.chat_bar->border_color=LTGRAY; } else { game.chat_bar->fg_color=LTRED; game.chat_bar->bg_color=WHITE; game.chat_bar->border_color=BLACK; } } U0 UnFocusChatBar() { game.chat_bar_active=FALSE; UIUnFocus; UITextBarSetText(game.chat_bar,"Press 'T' to talk"); } U0 UIChatBarEnterCb(CUIElem *,U8 *str){ if(game.player) { FrogSaySomethingToServer(game.player,str); } UnFocusChatBar; } U0 InitUI() { QueInit(&game.ui_root); game.chat_log=UIChatLogNew(GR_WIDTH/2.25/8,15,15); game.chat_log->bg_color=TRANSPARENT; game.chat_log->fg_color=LTRED; QueIns(game.chat_log,&game.ui_root); game.chat_bar=UITextBarNew("Press 'T' to talk",GR_WIDTH/2.25); game.chat_bar->fg_color=LTRED; game.chat_bar->bg_color=WHITE; game.chat_bar->border_color=BLACK; game.chat_bar->enter_cb=&UIChatBarEnterCb; QueIns(game.chat_bar,&game.ui_root); } class CPowerUp:CServerThing { U64 type; //is a char F64 x,y,rot; C2DObject *obj; U8 next_state[32]; }; U0 PowerUpDraw(CPowerUp *pu) { if(pu->obj) { pu->obj->x=pu->x; pu->obj->y=pu->y; pu->obj->rot=pu->rot; } } #define POWER_UPT_SEMENMAX 'SemenMax' class CSemenMaxPowerUp:CPowerUp { U8 *constructor dft "SemenMaxNew"; U8 *destroy dft "SemenMaxDel"; F64 end_tS precision 30; F64 spawn_tS precision 30; F64 spawn_x,spawn_y; F64 direction; }; $SP,"<15>",BI=15$ //Girlfreind frog $SP,"<16>",BI=16$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 $SP,"<17>",BI=17$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 extern CFrog *MakeGirlfreindFrog(CFrog *for_frog); CFrog *GetBoyfriendFrog() { I64 cnt=FrogCnt; CFrog *cur; while(--cnt>=0) if((cur=FrogN(cnt))->flags&FROGF_SEMENMAX) return cur; return NULL; } U0 SemenMaxPowerUpNextState(CSemenMaxPowerUp *pu) { CFrog *frog; I64 cnt; F64 state_time=Server_tS(game.server)-pu->spawn_tS; pu->x=pu->spawn_x+pu->direction*state_time*(GR_WIDTH/2.5); if(pu->x<0) { pu->x=0; pu->direction=1; pu->spawn_tS=Server_tS(game.server); } else if(pu->x>=GR_WIDTH) { pu->x=GR_WIDTH; pu->spawn_tS=Server_tS(game.server); pu->direction=-1; } pu->y=pu->spawn_y+Sin(state_time*pi)*75; cnt=FrogCnt; while(--cnt>=0) { frog=FrogN(cnt); if(C2DObjectCollisionTest(frog->tongue,pu->obj)) { frog->flags|=FROGF_SEMENMAX; frog->power_up_end_ts=Server_tS(game.server)+15; MakeGirlfreindFrog(frog); ServerThingDel(game.server,pu); return; } } } CPowerUp *SemenMaxNew(CSemenMaxPowerUp *semen) { semen->type=POWER_UPT_SEMENMAX; semen->spawn_tS=Server_tS(game.server); if(Rand>.5) { semen->spawn_x=0; semen->direction=1; } else { semen->spawn_x=GR_WIDTH; semen->direction=-1; } semen->obj=C2DObjectNewFromSprite($IB,"<15>",BI=15$,game.game_task); AddObjectToWorld(semen->obj,game.world); StrCpy(semen->next_state,"SemenMaxPowerUpNextState"); semen->spawn_x=0; semen->spawn_y=50; return semen; } U0 SemenMaxDel(CSemenMaxPowerUp *d) { C2DObjectDel(d->obj); Free(d); } C2DWorld *world=C2DWorldNew(CYAN); U0 DrawFly(CFly *fly) { if(!fly->body) { fly->body=C2DObjectNewFromSprite(fly1->sprite,game.game_task); AddObjectToWorld(fly->body,game.world); } if(Blink(FLY_ANIMATION_FREQ)) { if(fly->body->user_data!=fly1){ C2DObjectSetGraphicsFromSprite(fly->body,fly1->sprite); fly->body->user_data=fly1; } } else { if(fly->body->user_data!=fly2){ C2DObjectSetGraphicsFromSprite(fly->body,fly2->sprite); fly->body->user_data=fly2; } } C2DObjectMove(fly->body,fly->x,fly->y); fly->body->priority=FLY_DRAW_PRIORITY+Rand*1000; //TODO improve } U0 DrawWasp(CWasp *wasp) { Bool flipped=FALSE; if(!wasp->body) { wasp->body=C2DObjectNewFromSprite(wasp1->sprite,game.game_task); AddObjectToWorld(wasp->body,game.world); } if(Blink(FLY_ANIMATION_FREQ)) { if(wasp->body->user_data!=wasp1){ C2DObjectSetGraphicsFromSprite(wasp->body,wasp1->sprite); C2DObjectMoveCenter(wasp->body,-6*8,9*8); wasp->body->user_data=wasp1; } } else { if(wasp->body->user_data!=wasp2){ C2DObjectSetGraphicsFromSprite(wasp->body,wasp2->sprite); C2DObjectMoveCenter(wasp->body,-6*8,9*8); wasp->body->user_data=wasp2; } } if(wasp->state==1||wasp->state==2) { if(wasp->x>wasp->end_x) flipped=TRUE; wasp->body->rot=Arg(wasp->end_x-wasp->x,wasp->end_y-wasp->y); } else { if(wasp->xold_x) flipped=TRUE; wasp->body->rot=Arg(wasp->x-wasp->old_x,wasp->y-wasp->old_y); } if(wasp->is_angry) { wasp->body->flags|=C2DOBJF_REPLACE_COLOR; wasp->body->with_color=RED; wasp->body->replace_color=YELLOW; } C2DObjectSetFlip(wasp->body,flipped); if(wasp->body->rot<0) wasp->body->rot+=2*pi; if(flipped) wasp->body->rot+=pi; C2DObjectMove(wasp->body,wasp->x,wasp->y); wasp->body->priority=FLY_DRAW_PRIORITY+Rand*1000; //TODO improove } U0 FlyDel(CFly *fly) { if(fly->body) C2DObjectDel(fly->body); Free(fly); } U0 FlyMove(CFly *fly) { F64 t=(Server_tS(game.server)-fly->start_ts)*fly->speed; fly->old_x=fly->x; fly->old_y=fly->y; switch(fly->pattern) { case FLY_PATTERN_SINE: fly->x=fly->spawn_x+t; fly->y=fly->spawn_y+fly->sine_amplitude*Sin(t/FLY_SINE_DIVIDE); //If fly is no longer visible,we go to poo poo land if(fly->body) if(fly->x-fly->body->width>=GR_WIDTH) fly->done=TRUE; break; case FLY_PATTERN_BEZIER: fly->x=fly->spawn_x*(1-t)`2+2.*(1-t)*t*fly->btarget_x+t*t*fly->end_x; fly->y=fly->spawn_y*(1-t)`2+2.*(1-t)*t*fly->btarget_y+t*t*fly->end_y; if(t>=1) goto init_rand; break; case FLY_PATTERN_ZIP: fly->x=fly->spawn_x+(fly->end_x-fly->spawn_x)*t; fly->y=fly->spawn_y+(fly->end_y-fly->spawn_y)*t; if(t>=1) goto init_rand; break; } return; init_rand: if(fly->fly_type==FLYT_WASP) fly->done=1; if(++fly->actions_cnt==fly->actions_until_leave) { fly->pattern=FLY_PATTERN_ZIP; fly->end_y=-100; fly->spawn_x=fly->x; fly->spawn_y=fly->y; fly->end_x=RandU64%GR_WIDTH; fly->start_ts=Server_tS(game.server); fly->speed=1; return; } else if(fly->actions_cnt>fly->actions_until_leave) { fly->done=1; } fly->start_ts=Server_tS(game.server); fly->pattern=FLY_PATTERN_ZIP; fly->spawn_x=fly->x; fly->spawn_y=fly->y; fly->end_y=RandU64%GROUND_POSITION; fly->end_x=RandU64%GR_WIDTH; fly->speed=0.5; } U0 WaspMove(CWasp *wasp) { F64 t=(Server_tS(game.server)-wasp->start_ts)*wasp->speed,tx,ty; I64 i,cnt; CFrog *f; wasp->old_x=wasp->x; wasp->old_y=wasp->y; switch(wasp->pattern) { break;case FLY_PATTERN_SINE: case FLY_PATTERN_BEZIER: case FLY_PATTERN_ZIP: normal: FlyMove(wasp); break; case FLY_PATTERN_ATTACK: if(t<1) { wasp->x=wasp->spawn_x+(wasp->btarget_x-wasp->spawn_x)*t; wasp->y=wasp->spawn_y+(wasp->btarget_y-wasp->spawn_y)*t; } else if(t<2) { if(!wasp->state) { wasp->state=1; cnt=FrogCnt; f=FrogN(RandU64%cnt); wasp->target=f; } else { wasp->end_x=GR_WIDTH/2-Sign(wasp->x-GR_WIDTH/2)*GR_WIDTH/2; wasp->end_y=GR_HEIGHT+100; wasp->spawn_x=wasp->x; wasp->spawn_y=wasp->y; //https://stackoverflow.com/questions/6711707/draw-a-quadratic-b%C3%A9zier-curve-through-three-given-points tx=wasp->target->body->x; ty=wasp->target->body->y; wasp->btarget_x=2*tx-wasp->spawn_x/2-wasp->end_x/2; wasp->btarget_y=2*ty-wasp->spawn_y/2-wasp->end_y/2; wasp->state=2; } } else if(t<4) { wasp->start_ts=Server_tS(game.server); //Reset the timestamp for the bezier; wasp->state=2; wasp->speed=0.3; wasp->pattern=FLY_PATTERN_BEZIER; goto normal; } } DrawWasp(wasp); //Update properyties } CFly *FlyNew(I64 pattern,F64 x,F64 y) { CFly *fly=ConstructServerThing(game.game_task,"CFly"); QueInit(fly); fly->body=C2DObjectNewFromSprite(fly1->sprite,game.game_task); fly->start_ts=Server_tS(game.server); fly->speed=100; fly->fly_type=FLYT_FLY; fly->spawn_x=fly->x=x,fly->spawn_y=fly->y=y; fly->old_x=x,fly->old_y=y; fly->pattern=pattern; switch(fly->pattern) { case FLY_PATTERN_SINE: fly->actions_until_leave=0; fly->sine_amplitude=175; break; case FLY_PATTERN_ZIP: fly->actions_until_leave=3; fly->end_x=RandU64%GR_WIDTH; fly->end_y=RandU64%(GROUND_POSITION-75); break; case FLY_PATTERN_BEZIER: fly->actions_until_leave=3; fly->btarget_x=RandU64%GR_WIDTH; fly->btarget_y=RandU64%(GROUND_POSITION-75); fly->end_x=RandU64%GR_WIDTH; fly->end_y=RandU64%(GROUND_POSITION-75); break; } return fly; } CWasp *WaspNew(F64 x,F64 y) { CWasp *wasp=ConstructServerThing(game.game_task,"CWasp"); wasp->body=C2DObjectNewFromSprite(fly1->sprite,game.game_task); wasp->start_ts=Server_tS(game.server); wasp->speed=1; wasp->fly_type=FLYT_WASP; wasp->spawn_x=x,wasp->x=x,wasp->spawn_y=y,wasp->y=y; wasp->old_x=x,wasp->old_y=y; wasp->pattern=FLY_PATTERN_ZIP; wasp->end_x=RandU64%GR_WIDTH; wasp->end_y=50+RandU64%150; wasp->actions_until_leave=5; return wasp; } U0 DrawFrog(CFrog *frog) { CDC *tongue_dc; if(frog->flags&FROGF_DEAD) { if(frog->head->user_data!=frog->reference_head_dead){ C2DObjectSetGraphicsFromSprite(frog->head,frog->reference_head_dead->sprite); frog->head->user_data=frog->reference_head_dead; frog->head->flags|=C2DOBJF_REPLACE_COLOR; frog->head->replace_color=GREEN; frog->head->with_color=frog->color; //Center for sitting body is at (0,0) C2DObjectMoveCenter(frog->body,0,0); } if(frog->body->user_data!=frog->reference_sit){ C2DObjectSetGraphicsFromSprite(frog->body,frog->reference_sit->sprite); frog->body->user_data=frog->reference_sit; frog->body->flags|=C2DOBJF_REPLACE_COLOR; frog->body->replace_color=GREEN; frog->body->with_color=frog->color; //Center for sitting body is at (0,5) C2DObjectMoveCenter(frog->body,0,8*5); } if(frog->looking_at_xx&&0) { C2DObjectMove(frog->head,frog->x-0xe*8,frog->y+1*8); C2DObjectMove(frog->body,frog->x,frog->y); C2DObjectSetFlip(frog->head,1); C2DObjectSetFlip(frog->body,0); C2DObjectRotate(frog->head,0); C2DObjectRotate(frog->body,pi); } else{ C2DObjectMove(frog->head,(frog->body->width)+frog->x,frog->y+1*8); C2DObjectMove(frog->body,frog->x,frog->y); C2DObjectSetFlip(frog->head,0); C2DObjectSetFlip(frog->body,1); C2DObjectRotate(frog->head,0); C2DObjectRotate(frog->body,pi); } tongue_dc=DCNew(1,1); C2DObjectSetGraphics(frog->tongue,tongue_dc); DCDel(tongue_dc); return; } frog->body->rot=0; if(frog->flags&FROGF_SITTING) { if(frog->body->user_data!=frog->reference_sit){ C2DObjectSetGraphicsFromSprite(frog->body,frog->reference_sit->sprite); frog->body->user_data=frog->reference_sit; frog->body->flags|=C2DOBJF_REPLACE_COLOR; frog->body->replace_color=GREEN; frog->body->with_color=frog->color; // DCColorChg(frog->body->graphics,GREEN,frog->color); } //Center for sitting body is at (0,5) C2DObjectMoveCenter(frog->body,0,8*5); } else { if(frog->body->user_data!=frog->reference_jump){ C2DObjectSetGraphicsFromSprite(frog->body,frog->reference_jump->sprite); frog->body->user_data=frog->reference_jump; frog->body->flags|=C2DOBJF_REPLACE_COLOR; frog->body->replace_color=GREEN; frog->body->with_color=frog->color; } //Center for jumping body is at (0,0) C2DObjectMoveCenter(frog->body,8*2,8*0x5); } if(frog->flags&FROGF_MOUTH_OPEN) { if(frog->head->user_data!=frog->reference_head_open){ C2DObjectSetGraphicsFromSprite(frog->head,frog->reference_head_open->sprite); frog->head->user_data=frog->reference_head_open; frog->head->flags|=C2DOBJF_REPLACE_COLOR; frog->head->replace_color=GREEN; frog->head->with_color=frog->color; } //Center for sitting body is at (0,5) C2DObjectMoveCenter(frog->head,0,8*5); //(0,1) tongue_dc=DCNew(frog->tongue_length,16); DCFill(tongue_dc,RED); tongue_dc->color=BLACK; GrRect(tongue_dc,0,4,tongue_dc->width,8); C2DObjectSetGraphics(frog->tongue,tongue_dc); DCDel(tongue_dc); C2DObjectMoveCenter(frog->tongue,0,4); } else { if(frog->head->user_data!=frog->reference_head_close){ C2DObjectSetGraphicsFromSprite(frog->head,frog->reference_head_close->sprite); frog->head->flags|=C2DOBJF_REPLACE_COLOR; frog->head->user_data=frog->reference_head_close; frog->head->replace_color=GREEN; frog->head->with_color=frog->color; } //Center for sitting body is at (0,5) C2DObjectMoveCenter(frog->head,0,5*8); tongue_dc=DCNew(1,1); C2DObjectSetGraphics(frog->tongue,tongue_dc); DCDel(tongue_dc); } frog->head->priority=FROG_DRAW_PRIORITY+10*frog->priority+2; frog->body->priority=FROG_DRAW_PRIORITY+10*frog->priority; frog->tongue->priority=FROG_DRAW_PRIORITY+10*frog->priority+1; //Move the frog head and body C2DObjectMove(frog->body,frog->x,frog->y); //If our frog is looking to the left reflect the head and body if(frog->looking_at_xx) { //Head is located at (0xf,2) //But we are reversed,so move the head towards frog->x C2DObjectMove(frog->head,(frog->body->width-0xe*8)+frog->x,frog->y-3*8); C2DObjectMove(frog->tongue,(frog->body->width-0xe*8)+frog->x,frog->y-3*8); //We are reversed,so move frog->body over // Forwards (x)---> // Backwars <---(x+width) C2DObjectMove(frog->body,frog->x+frog->body->width,frog->y); //roation will be "reversed" C2DObjectPointTo(frog->head,frog->looking_at_x,frog->looking_at_y); C2DObjectPointTo(frog->tongue,frog->looking_at_x,frog->looking_at_y); //Have same angle on opposite side of pole if(frog->head->rot<0) frog->head->rot+=2*pi; if(frog->head->flipped) frog->head->rot+=pi; C2DObjectSetFlip(frog->head,1); C2DObjectSetFlip(frog->body,1); } else { //Head is located at (0xe,2) C2DObjectMove(frog->head,frog->x+0xe*8,frog->y-3*8); if(frog->tongue) C2DObjectMove(frog->tongue,frog->x+0xe*8,frog->y-3*8); if(frog->tongue) C2DObjectPointTo(frog->tongue,frog->looking_at_x,frog->looking_at_y); C2DObjectPointTo(frog->head,frog->looking_at_x,frog->looking_at_y); C2DObjectSetFlip(frog->head,0); C2DObjectSetFlip(frog->body,0); } if(frog->flags&FROGF_OBJECT_ON_TONGUE&&frog->flags&FROGF_MOUTH_OPEN&&frog->object_on_tongue) { C2DObjectMoveCenter( frog->object_on_tongue, frog->object_on_tongue->width/2, frog->object_on_tongue->height/2 ); frog->object_on_tongue->y=frog->tongue_length*Sin(frog->tongue->rot)+frog->tongue->y; frog->object_on_tongue->x=frog->tongue_length*Cos(frog->tongue->rot)+frog->tongue->x; frog->object_on_tongue->priority=frog->tongue->priority+1; } else if(frog->object_on_tongue) { C2DObjectDel(frog->object_on_tongue); frog->object_on_tongue=NULL; } } U0 InitLilyPad() { // //frogs - 3<= //lily_pad 2 //water 1 lily_pad->priority=2; water->priority=1; AddObjectToWorld(lily_pad,game.world); AddObjectToWorld(water,game.world); //Now we need to position to lily pad and water in the world //Set the center of the lily_pad to the middle C2DObjectMoveCenter(lily_pad,lily_pad->width/2,lily_pad->height/2); C2DObjectMoveCenter(water,water->width/2,water->height/2); C2DObjectMove(lily_pad,GR_WIDTH/2,GR_HEIGHT-9*FONT_HEIGHT); C2DObjectScale(lily_pad,1.5); C2DObjectMove(water,GR_WIDTH/2,GR_HEIGHT-8*FONT_HEIGHT); } U0 Init() { game.game_task=Fs; game.done=FALSE; InitUI; game.world=world; } #define SCOREBOARD_WIDTH 100 #define SCOREBOARD_HEIGHT 16 #define DAY_LENGTH 60 $SP,"<18>",BI=18$ $SP,"<19>",BI=19$ U0 DayCycleTask(CGame *game) { game->day_start=tS; static I64 sky_colors[5]={CYAN,LTBLUE,BLUE,DKGRAY,BLACK}; CDC*dummy; U8 *sprite; F64 cycle,sun_happiness=1,sun_angle,sun_cycle; game->sun=C2DObjectNewFromSprite($IB,"<18>",BI=18$,game->game_task); AddObjectToWorld(game->sun,game->world); for(;tS-game->day_startday_start)/DAY_LENGTH; switch(ToI64(cycle*5)) { //There are 5 cycles in 1 day start: game->world->background_color=sky_colors[ToI64(cycle*5)]; case 0: goto set_sun; break;case 1: goto set_sun; break;case 2: set_sun: //Sun lasts from 0<=<4 sun_cycle=(tS-game->day_start)/DAY_LENGTH*4; if(game->sun->user_data) Free(game->sun->user_data); sprite=SpriteInterpolate(Abs(Sin(tS)),$IB,"<18>",BI=18$,$IB,"<19>",BI=19$); C2DObjectSetGraphicsFromSprite(game->sun,sprite); game->sun->x=GR_WIDTH/2+(GR_WIDTH-200)/2*Cos(pi-sun_cycle*pi/2); game->sun->y=GR_HEIGHT-200+(GR_HEIGHT-200)*-Sin(pi-sun_cycle*pi/2); game->sun->user_data=sprite; break;case 3: break;case 4: end: } Sleep(100); } C2DObjectDel(game->sun); } U0 DrawIt(CTask *t,CDC *dc) { CServerThing *thing,*head; CFrog *cur_frog,*player=NULL; I64 cnt,idx=0,live; U8 *str; F64 x,y; // // Here's the deal. ThingHasClass uses Fs->hash_table,so use the // task hash table to check types // CHashTable *old_table=Fs->hash_table; Fs->hash_table=t->hash_table; head=&game.server->things; for(thing=head->next;thing!=head;thing=thing->next) { if(!StrCmp(thing->class_name,"CFrog")) DrawFrog(thing); else if(!StrCmp(thing->class_name,"CWasp")) DrawWasp(thing); else if(!StrCmp(thing->class_name,"CFly")) DrawFly(thing); else if(ThingHasClass("CPowerUp",thing)) PowerUpDraw(thing); } //World needs to be updated with the screen that we are drawing too DrawWorld(t,game.world); GrBlot(dc,0,0,game.world->scrn); //Heres the deal,we still need to draw the frog speech bubbles cnt=FrogCnt; for(thing=head->next;thing!=head;thing=thing->next) { if(!StrCmp(thing->class_name,"CFrog")) { cur_frog=thing; if(cur_frog->flags&FROGF_PLAYER) player=cur_frog; if(str=cur_frog->speech_text) { if(!cur_frog->head->flipped) { x=cur_frog->head->x+10*8; y=cur_frog->head->y-25; SpeechBubblePointTo(dc,str,x,y,x+100,y-75); } else { x=cur_frog->head->x-10*8; y=cur_frog->head->y-25; SpeechBubblePointTo(dc,str,x,y,x-100,y-75); } if(cur_frog->speech_end_tsspeech_text); cur_frog->speech_text=NULL; cur_frog->speech_end_ts=0; } } dc->color=GREEN; GrRect(dc,x=GR_WIDTH*ToF64(idx+1)/(cnt+1)-SCOREBOARD_WIDTH/2,y=GR_HEIGHT-3-SCOREBOARD_HEIGHT,SCOREBOARD_WIDTH,SCOREBOARD_HEIGHT); dc->color=RED; dc->thick=3; GrPrint(dc,x,y,"SCORE(%d):%d",idx,cur_frog->fly_count); for(live=0;livelives;live++) { dc->color=LTRED; dc->thick=6; GrPlot3(dc,x+live*8,y+FONT_HEIGHT/2+3,0); } idx++; } } if(game.game_over&&player&&Blink) { str=MStrPrint("Game Over(Score is %d)",player->fly_count); x=(GR_WIDTH-FONT_WIDTH*StrLen(str))/2; y=(GR_HEIGHT-FONT_HEIGHT/2)/2; GrPrint(dc,x,y,str); Free(str); str=MStrPrint("High Score is %d",high_score); x=(GR_WIDTH-FONT_WIDTH*StrLen(str))/2; y+=FONT_HEIGHT; GrPrint(dc,x,y,str); Free(str); } UpdateUIChatLogGr; RenderUI(dc,&game.ui_root,0,0,t->pix_width,t->pix_height); dc->color=YELLOW; GrPrint(dc,0,0,"%n\n",Server_tS(game.server)); Fs->hash_table=old_table; } U0 GameOver() { game.game_over=TRUE; if(game.player) { if(high_scorefly_count) RegWrite(REG_SCORE,"I64 high_score=%d;;\n",game.player->fly_count); } } U0 FrogBeginJump(CFrog *frog,F64 towards_x,F64 towards_y,F64 velo=FROG_JUMP_VELOCITY,Bool sound=FALSE) { if(frog->y>=GROUND_POSITION) frog->y=GROUND_POSITION-1; F64 x=towards_x-frog->x; F64 y=(frog->y-towards_y); F64 angle=Arg(x,y); F64 vh=velo*Sin(angle); F64 vx=velo*Cos(angle); frog->jump_start_x=frog->x; frog->jump_start_y=frog->y; frog->jump_start_angle=angle; frog->flags&=~FROGF_SITTING; frog->jump_start_ts=Server_tS(game.server); frog->yvelo+=vh; frog->xvelo+=vx; ServerPassMessageToAllClients(game.server,"Message_JumpNoise", "",0); } U0 FrogContinueJump(CFrog *frog) { F64 x=(Server_tS(game.server)-frog->jump_start_ts),vh; if(!(frog->flags&FROGF_SITTING)) { frog->y-=frog->yvelo*x; frog->x+=frog->xvelo*x; frog->yvelo-=FROG_GRAVITY*x; if(!(frog->flags&FROGF_LEAVE_STAGE)) { if(frog->x<0) { frog->x=0; if(frog->xvelo<0) frog->xvelo*=-1; } if(frog->x>=GR_WIDTH) { frog->x=GR_WIDTH-1; if(frog->xvelo>0) frog->xvelo*=-1; } } } if(frog->y>=GROUND_POSITION) { frog->y=GROUND_POSITION; frog->yvelo=0; frog->xvelo=0; frog->flags|=FROGF_SITTING; MemSet(frog->hit_bitmap,0,1+MAX_FROGS/8); } } I64 FrogCnt() { I64 cnt=0; CServerThing *thing,*head=&game.server->things; for(thing=head->next;thing!=head;thing=thing->next) { if(!StrCmp(thing->class_name,"CFrog")) cnt++; } return cnt; } CFrog *FrogN(I64 n) { CServerThing *thing,*head=&game.server->things; for(thing=head->next;thing!=head;thing=thing->next) { if(!StrCmp(thing->class_name,"CFrog")) if(--n<=0) return thing; } return NULL; } U0 FrogConstructor(CFrog *new_frog) { CDC *dc_dummy=DCNew(1,1); QueInit(&new_frog->ass_blast.turds); new_frog->flags=FROGF_SITTING; new_frog->looking_at_x=GR_WIDTH/2; new_frog->looking_at_y=GR_HEIGHT*3./4; new_frog->priority=FrogCnt; new_frog->ai_param1=0; new_frog->ai_param2=0; new_frog->ai_param3=0; new_frog->color=GREEN; new_frog->tongue=C2DObjectNewFromDC(dc_dummy,game.game_task); new_frog->body=C2DObjectNewFromDC(dc_dummy,game.game_task); new_frog->head=C2DObjectNewFromDC(dc_dummy,game.game_task); new_frog->lives=3; new_frog->reference_head_open=frog_head_open; new_frog->reference_head_close=frog_head_close; new_frog->reference_head_dead=frog_head_dead; new_frog->reference_jump=frog_jump; new_frog->reference_sit=frog_sit; AddObjectToWorld(new_frog->tongue,game.world); AddObjectToWorld(new_frog->body,game.world); AddObjectToWorld(new_frog->head,game.world); DCDel(dc_dummy); } CFrog *AddFrog(I64 player=FALSE,F64 x=0,F64 y=GROUND_POSITION-1) { CFrog *frog=ConstructServerThing(game.game_task,"CFrog"); AddThingToServer(frog,game.server); frog->x=x,frog->y=y; return frog; } //Returns the player that is doing the best(except for the current frog) CFrog *BestPlayer(CFrog *frog) { CFrog *frog2,*best_frog=frog; I64 cnt=FrogCnt; while(--cnt>=0) if((frog2=FrogN(cnt))->fly_count>=best_frog->fly_count) best_frog=frog2; return best_frog; } CFly *ClosestFly(CFrog *frog) { CFly *fly,*best_fly=NULL,*head=&game.server->things; F64 best_dist=F64_MAX,dist; for(fly=head->next;fly!=head;fly=fly->next) { if(ThingHasClass("CFly",fly)) switch(fly->fly_type) { break;case FLYT_FLY: dist=Sqrt((fly->x-frog->x)`2+(fly->y-frog->y)`2); if(best_dist>dist) { best_dist=dist; best_fly=fly; } } } return best_fly; } F64 AngleDiff(F64 a,F64 b) { if(a<0) a=2*pi-a; if(b<0) b=2*pi-b; if(a>b) return a-b; return b-a; } #define AI_ANGRY_WASP_IGNORE_RADIUS 100 #define AI_ANGRY_WASP_IGNORE_FORCE 125 #define AI_FLY_CLUMP_RADIUS 50 #define AI_FLY_PER_ASS_BLAST 4 #define AI_MINIMUM_ASS_BLAST_FLIES 3 #define AI_WASP_DANGER_ZONE 85 #define AI_JUMP_DIST (GR_WIDTH/2) //Find the amount of flies that are "clump"ed toghter // This is used by the AI to tell which cluster/"swarm" to chase I64 FlyClumpCnt(CFly *fly) { I64 clump=0; F64 x,y; CFly *cur,*head=&game.server->things; for(cur=head->next;cur!=head;cur=cur->next) { if(ThingHasClass("CFly",cur)) if(cur->fly_type==FLYT_FLY) { x=fly->body->x-cur->body->x; y=fly->body->y-cur->body->y; if(Sqrt(Sqr(x)+Sqr(y))<=AI_FLY_CLUMP_RADIUS) { clump++; } } } return clump; } F64 PushBackDist(F64 x,F64 y,F64 x2,F64 y2,F64 radius,F64 force) { F64 dist=Sqrt(Sqr(x2-x)+Sqr(y2-y)); if(dist>radius) return 0; return (radius-dist)*force; } I64 *FrogMovieMake(...) { F64 *ret=MAlloc((argc+1)*sizeof(I64)); I64 idx; for(idx=0;idxuser_data) return; //ai_state[0] is the current state(0 if looking for a new state) //ai_state[1] is the state end_time F64 *state=frog->user_data,x,y,velo,time; state+=frog->user_data2; if(frog->ai_state[0]==FROG_MOVIE_LOOK) { x=state[1]; y=state[2]; time=Server_tS(game.server)-frog->ai_state[1]; x=(x-frog->ai_state[2])*(time/state[3])+frog->ai_state[2]; y=(y-frog->ai_state[3])*(time/state[3])+frog->ai_state[3]; frog->looking_at_x=x; frog->looking_at_y=y; if(time>state[3]) { frog->user_data2+=4; //(state,x,y,velo) frog->ai_state[0]=0; return; } else return; } else if(frog->ai_state[0]==FROG_MOVIE_JUMP){ if(!(frog->flags&FROGF_SITTING)) return; frog->user_data2+=4; //(state,x,y,velo) frog->ai_state[0]=0; return; } else if(frog->ai_state[0]==FROG_MOVIE_STICK_OBJECT_TO_TONGUE) { time=(Server_tS(game.server)-frog->ai_state[1])/FROG_TONGUE_DURATION; if(pi>time>pi/2) { if(frog->object_on_tongue) C2DObjectDel(frog->object_on_tongue); frog->object_on_tongue=C2DObjectCopy(state[3](I64),game.game_task); AddObjectToWorld(frog->object_on_tongue,game.world); frog->flags|=FROGF_OBJECT_ON_TONGUE; return; } else if(timeobject_on_tongue) C2DObjectDel(frog->object_on_tongue); frog->object_on_tongue=NULL; return; } frog->user_data2+=4; //(state,x,y,2d-object) frog->ai_state[0]=0; return; } else if(frog->ai_state[0]==FROG_MOVIE_EAT) { time=(Server_tS(game.server)-frog->ai_state[1])/FROG_TONGUE_DURATION; if(timeuser_data2+=3; //(state,x,y) frog->ai_state[0]=0; } else if(frog->ai_state[0]==FROG_MOVIE_SHIT) { if(Server_tS(game.server)ai_state[1]) return; frog->user_data2+=3; //(state,turds,duration) frog->ai_state[0]=0; return; }else if(frog->ai_state[0]==FROG_MOVIE_SLEEP) { if(Server_tS(game.server)ai_state[1]) return; frog->user_data2+=2; //(state,duration) frog->ai_state[0]=0; return; } switch(state[0](I64)) { break;case 0: Free(frog->user_data); frog->user_data=NULL; break;case FROG_MOVIE_JUMP: x=state[1],y=state[2],velo=state[3]; if(velo==0) velo=FROG_JUMP_VELOCITY; frog->looking_at_x=x; frog->looking_at_y=y; FrogBeginJump(frog,x,y,velo,TRUE); frog->ai_state[0]=FROG_MOVIE_JUMP; break;case FROG_MOVIE_LOOK: x=state[1],y=state[2],time=state[3]; frog->ai_state[0]=FROG_MOVIE_LOOK; frog->ai_state[1]=Server_tS(game.server); frog->ai_state[2]=frog->looking_at_x; frog->ai_state[3]=frog->looking_at_y; break;case FROG_MOVIE_EAT: x=state[1],y=state[2]; frog->looking_at_x=x; frog->looking_at_y=y; frog->ai_state[0]=FROG_MOVIE_EAT; frog->ai_state[1]=Server_tS(game.server); frog->flags|=FROGF_MOUTH_OPEN; frog->tongue_start_ts=Server_tS(game.server); break;case FROG_MOVIE_STICK_OBJECT_TO_TONGUE: x=state[1],y=state[2]; frog->looking_at_x=x; frog->looking_at_y=y; frog->ai_state[0]=FROG_MOVIE_STICK_OBJECT_TO_TONGUE; frog->ai_state[1]=Server_tS(game.server); frog->flags|=FROGF_MOUTH_OPEN; frog->tongue_start_ts=Server_tS(game.server); break;case FROG_MOVIE_SHIT: InitAssBlastForFrog(frog,state[1]); frog->ai_state[1]=Server_tS(game.server)+state[2]; frog->ai_state[0]=FROG_MOVIE_SHIT; break;case FROG_MOVIE_SLEEP: frog->ai_state[1]=Server_tS(game.server)+state[1]; frog->ai_state[0]=FROG_MOVIE_SLEEP; break;case FROG_MOVIE_DONE: frog->ai_state[0]=FROG_MOVIE_DONE; } } U0 FrogAI0(CFrog *frog) { CFrog *best; //ai_param1 is tongue timeout //ai_state[0] is last tongue time Bool wants_jump=FALSE,wants_tongue=FALSE; F64 force,angle; I64 state=frog->ai_state[0]; CFly *cur_f,*head_f=&game.server->things,*best_clus_fly=NULL; I64 best_clus=0; for(cur_f=head_f->next;cur_f!=head_f;cur_f=cur_f->next) { if(ThingHasClass("CFly",cur_f)) if(cur_f->fly_type==FLYT_FLY) if(best_cluslooking_at_x=best->body->x; frog->looking_at_y=best->body->y-50; wants_jump=TRUE; wants_tongue=TRUE; } else if(!(frog->flags&FROGF_SHITTING)) if(AI_MINIMUM_ASS_BLAST_FLIES<=frog->flies_since_last_shit) if(best_clus*AI_FLY_PER_ASS_BLAST>3*frog->flies_since_last_shit) { ass_blast_for_flies: InitAssBlastForFrog(frog,3*frog->flies_since_last_shit); goto chase_fly; } chase_fly: if(best_clus_fly) { frog->looking_at_x=best_clus_fly->body->x; frog->looking_at_y=best_clus_fly->body->y; wants_jump=TRUE; wants_tongue=TRUE; avoid_wasps: for(cur_f=head_f->next;cur_f!=head_f;cur_f=cur_f->next) { if(cur_f->fly_type==FLYT_WASP) { if(cur_f(CWasp*)->is_angry) if(force=PushBackDist(frog->looking_at_x,frog->looking_at_y,cur_f->body->x, cur_f->body->y,AI_ANGRY_WASP_IGNORE_RADIUS, AI_ANGRY_WASP_IGNORE_FORCE)) { angle=Arg(cur_f->body->x-frog->looking_at_x,cur_f->body->y-frog->looking_at_y); frog->looking_at_x=cur_f->body->x+force*Sin(angle); frog->looking_at_y=cur_f->body->y+force*Cos(angle); } } } } close_to_angry_wasp: for(cur_f=head_f->next;cur_f!=head_f;cur_f=cur_f->next) { if(cur_f->fly_type==FLYT_WASP) { if(cur_f(CWasp*)->is_angry) { if(force=PushBackDist(frog->y,frog->x,cur_f->body->x, cur_f->body->y,AI_ANGRY_WASP_IGNORE_RADIUS/2, AI_ANGRY_WASP_IGNORE_FORCE/2)) { frog->looking_at_x=frog->x; frog->looking_at_y=frog->y; angle=Arg(cur_f->body->x-frog->looking_at_x,cur_f->body->y-frog->looking_at_y); frog->looking_at_x=cur_f->body->x+force*Sin(angle); frog->looking_at_y=cur_f->body->y+force*Cos(angle); if(frog->looking_at_y>GROUND_POSITION) frog->looking_at_y=GROUND_POSITION-20; wants_jump=TRUE; wants_tongue=FALSE; } } } } if(wants_tongue&&!(frog->flags&FROGF_MOUTH_OPEN)&&frog->ai_state[0]<=tS) { frog->ai_state[0]=Server_tS(game.server)+frog->ai_param1; frog->flags|=FROGF_MOUTH_OPEN; frog->tongue_length=FROG_TONGUE_MIN_LENGTH; frog->tongue_start_ts=Server_tS(game.server); } if(wants_jump) if((frog->flags&FROGF_SITTING)&&!(frog->flags&FROGF_SHITTING)) FrogBeginJump(frog,frog->looking_at_x,frog->looking_at_y,,TRUE); } U8 *RandSub(U8 *str) { I64 cnt=0; while(LstSub(cnt,str)) cnt++; if(!cnt--) return; cnt=RandU64%cnt; return LstSub(cnt,str); } #define FROG_TALK_WINNING "winning" #define FROG_TALK_LOOSING "loosing" #define FROG_TALK_FLY "fly" #define FROG_TALK_WASP "wasp" U0 FrogAI1Talk(CFrog *frog,U8 *flag) { if(TaskValidate(frog->chat_bot_task)) { FramePtrDel(FROG_TALK_WINNING,frog->chat_bot_task); FramePtrDel(FROG_TALK_LOOSING,frog->chat_bot_task); FramePtrDel(FROG_TALK_FLY,frog->chat_bot_task); FramePtrDel(FROG_TALK_WASP,frog->chat_bot_task); FramePtrAdd(flag,1,frog->chat_bot_task); } } U8 *ChatBotGetStr(CEliza *f) { //Todo text input from player CFrog *frog=f->user_data(CFrog*); CUIChatLogLine *ln; if(frog->speech_end_ts) Sleep((frog->speech_end_ts-Server_tS(game.server))*1000); Sleep(Rand*1500+500); for(ln=game.chat_log->lines.last;ln!=&game.chat_log->lines;ln=ln->last) { //Ignore ": " if(StrNCmp(ln->name,frog->name,StrLen(frog->name))) if(ln->num>FramePtr("last_proc_chat_line")) { FramePtrSet("last_proc_chat_line",ln->num); return StrNew(ln->text); } } return StrNew(""); } U0 ChatBotDispStr(CEliza *f,U8 *str) { CFrog *frog=f->user_data; I64 use_color=frog->color; //Birghter version of colors are in low+8; if(use_color<8) use_color+=8; str=MStrUtil(str,SUF_REM_CTRL_CHARS); if(frog->speech_text) Free(frog->speech_text); frog->speech_text=StrNew(str,game.game_task); frog->speech_end_ts=Server_tS(game.server)+2; FrogSaySomethingToServer(frog,str); Free(str); } CTask *Frog1ChatBot(CFrog *frog) { U8 *data=FileRead("Frog1.TXT"); frog->chat_bot_eliza=ElizaNew(data); frog->chat_bot_eliza->user_data=frog; frog->chat_bot_eliza->get_str=&ChatBotGetStr; frog->chat_bot_eliza->disp_str=&ChatBotDispStr; frog->chat_bot_task=Fs; StrCpy(frog->name,"Frog1"); Free(data); FramePtrAdd("last_proc_chat_line",0); ElizaChat(frog->chat_bot_eliza); } //The dumb frog,choose the closest fly and jump away U0 FrogAI1(CFrog *frog) { if(!frog->chat_bot_task) { frog->chat_bot_task=Spawn(&Frog1ChatBot,frog,"FrogAI1Chat",,Fs); } CFrog *best=BestPlayer(frog); CFly *fly=ClosestFly(frog); CWasp *wasp; F64 angle1,angle2,dist; Bool is_winning=TRUE,tried_fly=FALSE; U8 *data; if(best) is_winning=best->fly_countfly_count; if(frog->flags&FROGF_SHITTING&&fly) goto chase_fly; if(!frog->ai_state[1]) frog->ai_state[1]=tS; //ai_param1 is the maximum waiting time before next action //ai_param2 is percentage of time frog pesters best player //ai_param3 is jump_vecoity for pestering player //ai_param4 is the "mouse" move speed(Percent of desired location per frame) //ai_param5 is ass-blast probability when loosing //ai_param6 is ass-blast probability when winning //ai_state[0] is expected wait time. //ai_state[1] is time since last action. if(frog->ai_state[0]<=Server_tS(game.server)-frog->ai_state[1]) { if(frog->flags&FROGF_SITTING) { if(Randai_param2) goto pester_player; } chase_fly: tried_fly=TRUE; if(fly) { //Check to attempt to look away from a wasp angle1=Arg(frog->looking_at_x-frog->x,frog->looking_at_x-frog->y); for(wasp=game.server->things.next;wasp!=&game.server->things;wasp=wasp->next) { if(ThingHasClass("CFly",wasp)) switch(wasp->fly_type) { break;case FLYT_WASP: if(wasp->is_angry&&wasp->body) { FrogAI1Talk(frog,FROG_TALK_WASP); angle2=Arg(wasp->body->x-frog->x,wasp->body->y-frog->y); if(AngleDiff(angle1,angle2)looking_at_x=fly->x; frog->looking_at_y=fly->y; FrogAI1Talk(frog,FROG_TALK_FLY); if(!(frog->flags&FROGF_SHITTING)) { if(frog->flies_since_last_shit>3&&is_winning&&Randai_param5) { ass_blast: InitAssBlastForFrog(frog,3*frog->flies_since_last_shit); frog->flies_since_last_shit=0; return; } if(frog->flies_since_last_shit&&!is_winning&&Randai_param6) goto ass_blast; } done_look_at: angle1=Arg(frog->looking_at_x-frog->x,frog->looking_at_x-frog->y); dist=Sqrt(Sqr(frog->looking_at_x-frog->x)+Sqr(frog->looking_at_y-frog->y)) //ai_param4 is the percept per frame *Clamp(frog->ai_param4*(Server_tS(game.server)-frog->ai_state[0])/WINMGR_PERIOD,0,1); frog->looking_at_x=dist*Cos(angle1)+frog->x; frog->looking_at_y=dist*Sin(angle1)+frog->y; if(frog->flags&FROGF_SITTING) { frog->flags|=FROGF_MOUTH_OPEN; frog->tongue_length=FROG_TONGUE_MIN_LENGTH; frog->tongue_start_ts=Server_tS(game.server); FrogBeginJump(frog,frog->looking_at_x,frog->looking_at_y,,TRUE); goto competed_action; } } else { pester_player: if(is_winning) FrogAI1Talk(frog,FROG_TALK_WINNING); else FrogAI1Talk(frog,FROG_TALK_LOOSING); if(best!=frog) { //If we need flies,look for flies and not pester player if(fly&&frog->fly_countfly_count&&!tried_fly) { goto chase_fly; } frog->looking_at_x=best->x; //Jump above player frog as we are either sitting or jumping frog->looking_at_y=best->y-200; if(frog->flags&FROGF_SITTING) { frog->flags|=FROGF_MOUTH_OPEN; frog->tongue_length=FROG_TONGUE_MIN_LENGTH; frog->tongue_start_ts=Server_tS(game.server); FrogBeginJump(frog,frog->looking_at_x,frog->looking_at_y,frog->ai_param3,TRUE); competed_action: frog->ai_state[0]=Rand*frog->ai_param1; frog->ai_state[1]=Server_tS(game.server); } } } } } U0 GameWaitForClearWave() { CFly *fly,*head=&game.server->things; while(TRUE) { for(fly=head->next;fly!=head;fly=fly->next) { if(ThingHasClass("CFly",fly)) goto sleep; } break; sleep: Sleep(100); } } U0 FrogCloseMouth(CFrog *frog,C2DObject *obj=NULL) { F64 tongue_cycle,dist,angle; if(obj) { if(frog->object_on_tongue) C2DObjectDel(frog->object_on_tongue); frog->object_on_tongue=C2DObjectCopy(obj); frog->flags|=FROGF_OBJECT_ON_TONGUE; if(tongue_cyclex-frog->tongue->x)+Sqr(obj->y-frog->tongue->y)); tongue_cycle=(ASin((FROG_TONGUE_LENGTH-FROG_TONGUE_MIN_LENGTH)/dist)+pi/2)*FROG_TONGUE_DURATION; //frog->tongue_start_ts+=tongue_cycle-frog->tongue_start_ts; frog->flags|=FROGF_OBJECT_ON_TONGUE; AddObjectToWorld(frog->object_on_tongue,game.world); } } else frog->flags&=~(FROGF_MOUTH_OPEN|FROGF_OBJECT_ON_TONGUE); } class CFlyWave { CFly *fly; I64 rep_cnt; I64 spacing; }; CTask *FlyWaveTask(CFlyWave *fw) { CFly *fly=fw->fly; I64 rep_cnt=fw->rep_cnt,time_spacing=fw->spacing; I64 idx; CFly *new; if(rep_cnt) { for(idx=0;idx!=rep_cnt;idx++) { new=FlyNew(fly->pattern,fly->x,fly->y); MemCpy(&new->pattern_info_start,&fly->pattern_info_start,sizeof(CFly) -offset(CFly.pattern_info_start)); new->start_ts=Server_tS(game.server); DrawFly(new); //Set properties AddObjectToWorld(new->body,game.world); QueInit(new); AddThingToServer(new,game.server); Sleep(time_spacing); } } Free(fw); } CTask *GameCreateWaveFromFly(CFly *fly,I64 rep_cnt,I64 spacing) { CFlyWave *fw=CAlloc(sizeof(CFlyWave),game.game_task); fw->fly=fly; fw->rep_cnt=rep_cnt; fw->spacing=spacing; return Spawn(&FlyWaveTask,fw,,,Fs); } class CWaspWave { I64 rep_cnt; I64 time_spacing; }; U0 WaspWaveTask(CWaspWave *data) { I64 rep_cnt=data->rep_cnt,time_spacing=data->time_spacing; I64 idx; CWasp *wasp; if(rep_cnt) { for(idx=0;idx!=rep_cnt;idx++) { wasp=WaspNew(RandU64%GR_WIDTH,50+100%RandU64); wasp->start_ts=Server_tS(game.server); AddObjectToWorld(wasp->body,game.world); DrawWasp(wasp); //Set properties AddThingToServer(wasp,game.server); Sleep(time_spacing); } } Free(data); } CTask *GameCreateWaspWave(I64 rep_cnt,I64 spacing) { CWaspWave *ww=CAlloc(sizeof(CWaspWave),game.game_task); ww->rep_cnt=rep_cnt; ww->time_spacing=spacing; return Spawn(&WaspWaveTask,ww,,,Fs); } U0 FrogDie(CFrog *frog) { Sweep(200,50,45); frog->flags|=FROGF_DEAD; frog->death_penalty_wait_until=Server_tS(game.server)+FROG_DEATH_TIME; } U0 GameLevel0(I64 d) { //TODO startup music CTask *fly_wave,*wasp_wave; InitLilyPad; CFly *template; CFrog *cpu=AddFrog(FALSE,400); cpu->color=RED; StrCpy(cpu->ai,"FrogAI1"); // cpu->ai=&FrogAIMovieScene; cpu->user_data=FrogMovieMake( FROG_MOVIE_JUMP,100.,0.,1., FROG_MOVIE_LOOK,1,300.,1., FROG_MOVIE_EAT,10.,10., FROG_MOVIE_SLEEP,1., FROG_MOVIE_EAT,640.,30., FROG_MOVIE_SHIT,15. ); cpu->ai_param1=.75; cpu->ai_param2=0.75; cpu->ai_param3=FROG_JUMP_VELOCITY*.75; cpu->ai_param4=1; cpu->ai_param5=.5; cpu->ai_param6=.25; //Wave 1 template=FlyNew(FLY_PATTERN_SINE,0,100); fly_wave=GameCreateWaveFromFly(template,10,100); wasp_wave=GameCreateWaspWave(1,1000/3); DeathWait(&fly_wave); DeathWait(&wasp_wave); GameWaitForClearWave; //Wave 2 ServerThingDel(game.server,template); AddThingToServer(ConstructServerThing(game.game_task,"CSemenMaxPowerUp"),game.server); template=FlyNew(FLY_PATTERN_BEZIER,0,100); template->speed=0.5; template->end_x=GR_WIDTH; template->end_y=100; template->btarget_x=GR_WIDTH/2; template->btarget_y=GROUND_POSITION; fly_wave=GameCreateWaveFromFly(template,10,100); wasp_wave=GameCreateWaspWave(1,1000/3); DeathWait(&fly_wave); DeathWait(&wasp_wave); GameWaitForClearWave; ServerThingDel(game.server,template); //Wave 3 template=FlyNew(FLY_PATTERN_SINE,GR_WIDTH,100); template->speed*=-1; fly_wave=GameCreateWaveFromFly(template,10,100); wasp_wave=GameCreateWaspWave(2,1000/5); DeathWait(&fly_wave); DeathWait(&wasp_wave); GameWaitForClearWave; ServerThingDel(game.server,template); } //Vagina $SP,"<20>",BI=20$ //123456789abcdef12345678 //2 //3 //4 //5 //6 //7 //8 //Abortion table $SP,"<21>",BI=21$ //Fetus $SP,"<22>",BI=22$ U0 AbortionSceneLevel(I64) { GameClear; I64 old_world=game.world,old_gp=GROUND_POSITION,old_t=FROG_TONGUE_DURATION; GROUND_POSITION=350; FROG_TONGUE_DURATION=.5; CFrog *frog=AddFrog(FALSE,0,GROUND_POSITION); StrCpy(frog->ai,"FrogAIMovieScene"); frog->x=0,frog->y=GROUND_POSITION; C2DObject *table=C2DObjectNewFromSprite($IB,"<21>",BI=21$,game.game_task); C2DObject *pussy=C2DObjectNewFromSprite($IB,"<20>",BI=20$,game.game_task); C2DObject *fetus=C2DObjectNewFromSprite($IB,"<22>",BI=22$,game.game_task); C2DObjectMoveCenter(table,0,0); C2DObjectMoveCenter(pussy,0,0); frog->user_data=FrogMovieMake( FROG_MOVIE_JUMP,ToF64(8*0x18),ToF64(GROUND_POSITION-8*0x18),50., FROG_MOVIE_LOOK,ToF64(516),ToF64(GROUND_POSITION-20),.3, FROG_MOVIE_STICK_OBJECT_TO_TONGUE,ToF64(516),ToF64(GROUND_POSITION-20),fetus, FROG_MOVIE_SLEEP,.75, FROG_MOVIE_LOOK,ToF64(GR_WIDTH*.75),ToF64(GR_HEIGHT/2),.1, FROG_MOVIE_SHIT,50. ); pussy->x=0x18*8; pussy->priority=frog->body->priority-1; table->priority=frog->body->priority-2; pussy->y=GROUND_POSITION-8*8; table->y=GROUND_POSITION; table->x=0; AddObjectToWorld(pussy,game.world); AddObjectToWorld(table,game.world); while(frog->ai_state[0]!=FROG_MOVIE_DONE) Sleep(100); C2DObjectDel(table); C2DObjectDel(pussy); C2DObjectDel(fetus); C2DWorldDel(game.world); FROG_TONGUE_DURATION=old_t; GROUND_POSITION=old_gp; } // // Server Message Section // class CChatMessage { I64 player_id; U8 message[256-8]; }; U0 Message_ServerChatMessage(CServer *s,CMessagePass *pass) { CChatMessage *chat=pass->body; CFrog *f=ServerId2Ptr(game.server,chat->player_id); I64 color=LTGRAY; U8 *name="Server"; if(f&&ThingHasClass("CFrog",f)) { name=f->name; color=f->color; if(f->speech_text) Free(f->speech_text); f->speech_text=StrNew(chat->message,game.game_task); f->speech_end_ts=Server_tS(s)+2; } name=MStrPrint("%s:",name); UIChatLogAddLine(game.chat_log,name,chat->message,color); Free(name); ServerPassMessageToAllClients(game.server,"Message_ClientChatMessage",pass->body,sizeof(CChatMessage)); } class CPlayerJoin { I64 token; U8 name[STR_LEN]; }; U0 Message_PlayerJoin(CServer *s,CMessagePass *pass) { //TODO which client CPlayerJoin *pd=pass->body; U8 *name,*str2; CFrog *f=AddFrog(TRUE,100,GROUND_POSITION-10); name=UDPAddrToStr(CurrentClient->to); FramePtrAdd(str2=MStrPrint("PLAYER_FROG:%s",name),f->id); PrintI(str2,1001); StrCpy(f->name,pd->name); Free(name),Free(str2); } U0 Message_LookAt(CServer *s,CMessagePass *pass) { CFrog *f=GetPlayerFrog(s); CD2I64 *ud=pass->body; if(!f) return; f->looking_at_x=ud->x; f->looking_at_y=ud->y; } U0 Message_JumpTowards(CServer *s,CMessagePass *pass) { CFrog *f=GetPlayerFrog(s); if(!f) return; if(!(f->flags&FROGF_MOUTH_OPEN)) { f->flags|=FROGF_MOUTH_OPEN; f->tongue_length=FROG_TONGUE_MIN_LENGTH; f->tongue_start_ts=Server_tS(game.server); } if(f->flags&FROGF_SITTING&&!(f->flags&FROGF_DEAD)) FrogBeginJump(f,f->looking_at_x,f->looking_at_y,,TRUE); } U0 Message_AssBlast(CServer *s,CMessagePass *pass) { CFrog *f=GetPlayerFrog(s); if(!f) return; //Create an ass blast based on how many flies you ate if(f->flies_since_last_shit&&!(f->flags&FROGF_SHITTING)) InitAssBlastForFrog(f,3*f->flies_since_last_shit); } U0 Message_ServerPlayerWhoAmI(CServer *s,CMessagePass *pass) { U8 *name,*str2; name=UDPAddrToStr(CurrentClient->to); CFrog *f=ServerId2Ptr(s,FramePtr(str2=MStrPrint("PLAYER_FROG:%s",name))); Free(name),Free(str2); if(f) ServerPassMessageToClient(s,"Message_ClientPlayerWho",&f->id,sizeof(I32)); } U0 Message_ClientPlayerWho(CServer *s,CMessagePass *pass) { CFrog *f=ServerId2Ptr(s,pass->body(I32*)[0]); if(f&&ThingHasClass("CFrog",f)) { game.player=f; } } U0 Message_JumpNoise(CServer *s,CMessagePass *pass) { Kill(game.sound_task); game.sound_task=Sweep(300,50,70); } U0 Message_StartAssBlastForFrog(CServer *s,CMessagePass *pass) { I64 id=pass->body(I64*)[0]; I64 turds=pass->body(I64*)[1]; CFrog *f=ServerId2Ptr(s,id); if(!f) return; if(ThingHasClass("CFrog",f)) if(f->flies_since_last_shit&&!(f->flags&FROGF_SHITTING)) InitAssBlastForFrog(f,turds); } U0 Message_EndAssBlastForFrog(CServer *s,CMessagePass *pass) { I64 id=pass->body(I64*)[0]; CFrog *f=ServerId2Ptr(s,id); if(!f) return; if(ThingHasClass("CFrog",f)) AssBlastFinish(f); } U0 FrogSaySomethingToServer(CFrog *f,U8 *message) { CChatMessage msg; msg.player_id=f->id; StrCpy(msg.message,message); ClientPassMessage(game.server,"Message_ServerChatMessage",&msg,sizeof(CChatMessage)); } U0 Message_ClientChatMessage(CServer *s,CMessagePass *pass) { CChatMessage *chat=pass->body; CFrog *f=ServerId2Ptr(game.server,chat->player_id); I64 color=LTGRAY; U8 *name="Server"; if(f&&ThingHasClass("CFrog",f)) { name=f->name; color=f->color; if(f->speech_text) { Free(f->speech_text); f->speech_text=NULL; } f->speech_text=StrNew(chat->message,game.game_task); } name=MStrPrint("%s:",name); UIChatLogAddLine(game.chat_log,name,chat->message,color); Free(name); } // // Client section // extern U0 ServeGame(CServer *server); #define GAMEF_DAY_CYCLE 1 #define GAMEF_CHAT_LOG 2 //Only 1 unqiue thing of each type is accepted class CFrogMsg { U8 name[STR_LEN-1]; Bool fired; CD2I64 pair; }; U0 FrogMsgFire(CFrogMsg *msg) { if(msg->fired) return ; msg->fired=TRUE; ClientPassMessage(game.server,msg->name,&msg->pair,sizeof(CD2I64)); } U0 FrogsClient(U8 *host,I64 port,I64 game_flags) { Fs->task_end_cb=&GameDel; game.game_task=Fs; CServer *client=ClientNew(host,port); game.server=client; CServerThing *thing,*head=&client->things; I64 msg,arga,argb; CFrogMsg look_msg; CFrogMsg jump_msg; CFrogMsg ass_blast_msg; CPlayerJoin player_join; if(Define("GAME_TOKEN")&&Define("PLAYER_NAME")) { Sleep(200); player_join.token=Str2I64(Define("GAME_TOKEN")); StrCpy(player_join.name,Define("PLAYER_NAME")); } look_msg.fired=TRUE; jump_msg.fired=TRUE; ass_blast_msg.fired=TRUE; CD2I64 pair; SettingsPush; WinMax; WinBorder; DocClear; AutoComplete; InitLilyPad; Fs->draw_it=&DrawIt; if(game_flags&GAMEF_DAY_CYCLE) game.day_task=Spawn(&DayCycleTask,&game,"Day",,Fs); ClientAskForUpdates(game.server); Beep; ClientPassMessage(client,"Message_PlayerJoin",&player_join,sizeof(CPlayerJoin)); while(!game.done) { for(thing=head->next;thing!=head;thing=thing->next) { if(ThingHasClass("CFrog",thing)) { ContinueAssBlast(thing); } } if(MSG_MS_MOVE==(msg=ScanMsg(&arga,&argb,1<no_yield=TRUE; if(ClientAskForUpdates(client)) { FrogMsgFire(&ass_blast_msg); FrogMsgFire(&look_msg); FrogMsgFire(&jump_msg); PrintI("ping",__GetTicks-gt); } if(!game.player) ClientPassMessage(game.server,"Message_ServerPlayerWhoAmI","",0); Refresh; } Fs->draw_it=NULL; Refresh; Kill(game.day_task); SettingsPop; C2DWorldDel(game.world); } // // // U0 ServeGame(CServer *server) { CServerThing *thing,*head,*next,*thing2; CFrog *frog,*other_frog; CD2I64 hit_at; I64 arga,argb,msg,ms=__GetTicks; F64 x,y,angle; F64 tongue_cycle; CFly *fly; CTask *level,*day; Fs->task_end_cb=&GameDel; if(game.server->mode!=SERV_MODE_CLIENT) { game.game_task=Fs; game.world=world; game.done=FALSE; if(game.level_task) { level=Spawn(game.level_task,&game,"Level",,Fs); BirthWait(&level); game.level_task=NULL; } } head=&server->things; for(thing=head->next;thing!=head;thing=next) { next=thing->next; if(ThingHasClass("CPowerUp",thing)) { CallExtStr(thing(CPowerUp*)->next_state,thing); } else if(ThingHasClass("CFrog",thing)) { frog=thing; if(frog->flags&FROGF_DEAD) { if(Server_tS(game.server)>=frog->death_penalty_wait_until) { if(--frog->lives<=0) { /* if(GetPlayerFrog(game.server)==frog) { game.game_over=TRUE; } else*/ ServerThingDel(game.server,frog); } else { frog->flags&=~FROGF_DEAD; } } } if(frog->flags&FROGF_MOUTH_OPEN) { tongue_cycle=(Server_tS(game.server)-frog->tongue_start_ts)/FROG_TONGUE_DURATION; if(tongue_cycle>pi) FrogCloseMouth(frog); frog->tongue_length=(FROG_TONGUE_LENGTH-FROG_TONGUE_MIN_LENGTH)*Sin(tongue_cycle)+FROG_TONGUE_MIN_LENGTH; } if(frog->flags&FROGF_SEMENMAX) { if(frog->power_up_end_tsflags&=~FROGF_SEMENMAX; } } if(game.server->mode==SERV_MODE_SERVER) { if(StrLen(frog->ai)) CallExtStr(frog->ai,frog); } FrogContinueJump(frog); ContinueAssBlast(frog); if(frog->tongue&&!(frog->flags&FROGF_DEAD)) { for(thing2=head->next;head!=thing2;thing2=thing2->next) { if(ThingHasClass("CFly",thing2)) { fly=thing2; if(fly->body) { if(C2DObjectCollisionTest(frog->tongue,fly->body)) { switch(fly->fly_type) { break;case FLYT_FLY: //Girlfreind frogs help the FROGF_SEMENMAX frog if(frog->flags&FROGF_GIRLFREIND) { if(GetBoyfriendFrog) { GetBoyfriendFrog->fly_count++; } } else frog->fly_count++; frog->flies_since_last_shit++; FrogCloseMouth(frog,fly->body); ServerThingDel(game.server,fly); goto next_frog_tongue; break;case FLYT_WASP: if(fly(CWasp*)->is_angry) { FrogDie(frog); ServerThingDel(game.server,fly); goto next_frog_tongue; } else { fly(CWasp*)->is_angry=TRUE; fly->pattern=FLY_PATTERN_ATTACK; fly->start_ts=Server_tS(game.server); fly->spawn_x=fly->body->x; fly->spawn_y=fly->body->y; fly->btarget_x=ClampI64(frog->body->x+RandI64%100,0,GR_WIDTH); fly->btarget_y=ClampI64(frog->body->y-200+RandI64%50,10,GR_HEIGHT/2); FrogCloseMouth(frog); goto next_frog_tongue; } } } } } } } next_frog_tongue: if(frog->y>=GROUND_POSITION) { frog->hit_vector=0; } // for(other_frog=head->next;other_frog!=head;other_frog=other_frog->next) { if(!ThingHasClass("CFrog",other_frog)) goto skip_other_frog; if(frog!=other_frog) { if(frog->flags&FROGF_MOUTH_OPEN&&!(frog->flags&FROGF_DEAD)) { if(C2DObjectCollisionTest(frog->tongue,other_frog->body)) { tongue_hit: if(frog->tongue->graphics) FrogCloseMouth(frog); goto next_frog_tongue2; } else if(C2DObjectCollisionTest(frog->tongue,other_frog->head)) { goto tongue_hit; } else if(C2DObjectCollisionTest(frog->tongue,other_frog->tongue)) { goto tongue_hit; } } } next_frog_tongue2:; if(frog!=other_frog&&!(frog->flags&FROGF_DEAD)) { if(C2DObjectCollisionTest(frog->body,other_frog->body)) { body_hit: if(!(frog->flags&FROGF_SITTING)) if(!Bts(&frog->hit_bitmap,other_frog->id2)) { if(frog->y>=other_frog->y) { FrogBeginJump(frog,frog->looking_at_x,frog->y+100,200,TRUE); if(frog->x>=other_frog->x) FrogBeginJump(frog,frog->x-100,other_frog->y-100,100,TRUE); else FrogBeginJump(frog,frog->x+100,other_frog->y-100,100,TRUE); break; } } } else if(C2DObjectCollisionTest(frog->body,other_frog->head)) { goto body_hit; } else if(C2DObjectCollisionTest(frog->body,other_frog->tongue)) { goto body_hit; } } skip_other_frog:; } } else if(ThingHasClass("CFly",thing)) { fly=thing; if(fly->done) { ServerThingDel(game.server,fly); } else{ if(fly->fly_type==FLYT_FLY) FlyMove(fly); else if(fly->fly_type==FLYT_WASP) WaspMove(fly); } } } if(game.server->mode!=SERV_MODE_CLIENT) { //Update propeties head=&game.server->things; for(thing=head->next;thing!=head;thing=thing->next) { if(!StrCmp(thing->class_name,"CFrog")) DrawFrog(thing); else if(!StrCmp(thing->class_name,"CWasp")) DrawWasp(thing); else if(!StrCmp(thing->class_name,"CFly")) DrawFly(thing); else if(ThingHasClass("CPowerUp",thing)) PowerUpDraw(thing); } } } U0 AssBlastFinish(CFrog *f) { CTurd *t,*tn; if(QueCnt(&f->ass_blast.turds)) { for(t=f->ass_blast.turds.next;t!=&f->ass_blast.turds;t=tn) { tn=t->next; TurdProjectileDel(t); } } QueInit(&f->ass_blast.turds); ServerPassMessageToAllClients(game.server,"Message_EndAssBlastForFrog",&f->id,sizeof(I64)); } U0 InitAssBlastForFrog(CFrog *f,I64 turds,Bool propel_into_air=TRUE) { CTurd *t,*tn; CD2I64 pair; if(!turds) return; if(!f->ass_blast.turds.next) QueInit(&f->ass_blast.turds); f->flies_since_last_shit=0; f->ass_blast.freq=15; f->ass_blast.duration=ToF64(turds)/10; f->ass_blast.start_ts=tS; f->ass_blast.next_turd_ts=tS; f->ass_blast.propel_into_air=propel_into_air; f->flags|=FROGF_SHITTING; pair.x=f->id; pair.y=turds; ServerPassMessageToAllClients(game.server,"Message_StartAssBlastForFrog",&pair,sizeof(CD2I64)); } U0 ContinueAssBlast(CFrog *f) { CTurd *turd,*tn; for(turd=f->ass_blast.turds.next;turd!=&f->ass_blast.turds;turd=tn) { tn=turd->next; if(turd->state==TURDS_DONE) { TurdProjectileDel(turd); } else TurdProjectileMove(turd); } if(!(f->flags&FROGF_SHITTING)) return; F64 t=tS-f->ass_blast.start_ts,x,y,vx,vy,angle; if(t>f->ass_blast.duration) { f->flags&=~FROGF_SHITTING; } else if(tS>f->ass_blast.next_turd_ts) { f->ass_blast.next_turd_ts=tS+1./f->ass_blast.freq; turd=CAlloc(sizeof CTurd); turd->start_ts=tS; turd->state=TURDS_PROJECTILE; turd->turdg=C2DObjectNewFromSprite($IB,"<12>",BI=12$,game.game_task); turd->turdg->priority=TURD_DRAW_PRIORITY+f->id2*FROG_DRAW_PRIORITY+QueCnt(&f->ass_blast.turds); f->flags|=FROGF_SHITTING; if(f->ass_blast.propel_into_air) { //Shitting will propel the fucking frog into the air f->y-=turd->turdg->height; x=f->looking_at_x-f->x; y=f->looking_at_y-f->y; angle=Arg(x,y); vy=-FROG_SHIT_VELOCITY*Sin(angle); vx=FROG_SHIT_VELOCITY*Cos(angle)*Abs(Rand); f->jump_start_x=f->x; f->jump_start_y=f->y; turd->xvelo=-vx; f->jump_start_angle=angle; f->flags&=~FROGF_SITTING; f->jump_start_ts=tS; f->yvelo+=vy; f->xvelo+=vx; turd->turdg->x=f->x; turd->turdg->y=f->y; } else{ turd->turdg->x=f->x; turd->turdg->y=f->y-20; if(f->body->flipped){ vy=-FROG_SHIT_VELOCITY*Sin(pi+pi/8); vx=FROG_SHIT_VELOCITY*Cos(pi+pi/8)*Abs(Rand); turd->turdg->x+=+0xe*8; } else { vy=-FROG_SHIT_VELOCITY*Sin(pi+pi/8); vx=-FROG_SHIT_VELOCITY*Cos(pi+pi/8)*Abs(Rand); } turd->xvelo=-vx; } C2DObjectUpdateMat(turd->turdg); AddObjectToWorld(turd->turdg,game.world); QueIns(turd,f->ass_blast.turds.last); if(game.sound_task&&!TaskValidate(game.shit_sound_task)) { Kill(game.sound_task); game.sound_task=ShitSound2(1000./f->ass_blast.freq,,,,f->ass_blast.duration/ToF64(f->ass_blast.freq)); game.shit_sound_task=game.sound_task; } } } U0 TurdProjectileMove(CTurd *p) { F64 t=tS-p->start_ts,old_x=p->turdg->x,old_y=p->turdg->y; CFrog *frog; switch(p->state) { break;case TURDS_PROJECTILE: C2DObjectSetGraphicsFromSprite(p->turdg,$IB,"<12>",BI=12$); p->turdg->x+=p->xvelo; p->turdg->y+=p->yvelo; if(p->xvelo<0) C2DObjectSetFlip(p->turdg,TRUE); p->turdg->rot=Arg(p->xvelo,p->yvelo); p->yvelo=t*TURD_GRAVITY; if(p->turdg->x<0) { p->turdg->x; goto become_splat; } if(p->turdg->x>=GR_WIDTH) { p->turdg->x=GR_WIDTH; goto become_splat; } if(p->turdg->y>=GROUND_POSITION) { p->turdg->y=GROUND_POSITION; goto become_ground; } return ; become_splat: p->state=TURDS_MELT; p->start_ts=tS; p->xvelo=0; p->yvelo=TURD_MELT_SPEED; p->melt_percent=0; return; become_ground: p->state=TURDS_GROUND; p->start_ts=tS; p->xvelo=0; p->yvelo=0; p->melt_percent=0; return; break;case TURDS_MELT: p->turdg->rot=0; p->turdg->x+=p->xvelo; p->turdg->y+=p->yvelo; C2DObjectSetGraphicsFromSprite(p->turdg,$IB,"<13>",BI=13$); if(p->turdg->xturdg,TRUE); } if(p->turdg->y>=GROUND_POSITION) { p->turdg->y=GROUND_POSITION; goto become_ground; } break;case TURDS_GROUND: case TURDS_STEPPED_ON: C2DObjectSetGraphicsFromSprite(p->turdg,$IB,"<14>",BI=14$); p->turdg->rot=0; if(t>=0.75) { free: p->state=TURDS_DONE; } else { C2DObjectScale(p->turdg,1-t); } } } //"Reset" the game data(Including world graphics) U0 GameClear() { CQue *obj,*next; game.player=NULL; if(game.sound_task) Kill(game.sound_task); if(game.day_task) Kill(game.day_task); for(obj=game.server->things;obj!=&game.server->things;obj=obj->next) { ServerThingDel(game.server,obj); } for(obj=game.world->objects.next;obj!=&game.world->objects;obj=next) { next=obj->next; C2DObjectDel(obj); } game.done=FALSE; } U0 GirlfreindFrogAI(CFrog *gf) { CFrog *loves_frog=GetBoyfriendFrog; if(loves_frog) goto found; goto leave; found: if(gf->ai_state[2]==1) { leave: if(gf->x<=-200.) { gf->lives=0; gf->flags|=FROGF_DEAD; return; } gf->flags|=FROGF_LEAVE_STAGE; gf->looking_at_x=-300; gf->looking_at_y=GROUND_POSITION-100; if(!(gf->flags&FROGF_SITTING)) return; FrogBeginJump(gf,gf->looking_at_x,gf->looking_at_y,FROG_JUMP_VELOCITY/2,TRUE); return; } if(loves_frog->power_up_end_ts<=Server_tS(game.server)) { gf->ai_state[2]=1; Free(gf->speech_text); gf->speech_text=StrNew("Im bored\ngunna find\another frog",game.game_task); gf->speech_end_ts=Server_tS(game.server)+.75; goto leave; } //Frog FrogAI0(gf); } CFrog *MakeGirlfreindFrog(CFrog *for_frog) { CFrog *cpu=AddFrog(FALSE,400); cpu->flags=FROGF_GIRLFREIND; cpu->color=LTPURPLE; StrCpy(cpu->ai,"GirlfreindFrogAI"); cpu->reference_head_open=C2DObjectNewFromSprite($IB,"<16>",BI=16$,game.game_task); cpu->reference_head_close=C2DObjectNewFromSprite($IB,"<17>",BI=17$,game.game_task); cpu->lives=1; } Init; #ifdef LOBBY_SERVER #include "lobby.HC" CStartGame *StartGame() { CStartGame *ret=CAlloc(sizeof CStartGame); StrCpy(ret->host,"127.0.0.1"); ret->port=8000; StrCpy(ret->path,#exe {StreamPrint("\"%s\"",__FILE__);;});; return ret; } LobbyServerNew(&StartGame,,,"Demo Lobby"); LobbyServerWaitForGame; LobbyDel;; #endif #ifdef LOBBY_CLIENT LobbyClientNew; LobbyInteract; LobbyDel; #endif $ER$#ifdef SERVER game.game_task=Fs; game.level_task=&GameLevel0; game.server=ServerNew(GAME_HOST,GAME_PORT); game.server->idle=&ServeGame; WinBorder; WinMax; Sleep(100); while(TaskValidate(game.server->server_task)) Sleep(1000); //User("#define CLIENT\n#include \"/Engine/Frogs/frogs.HC\";\n"); #endif #ifdef CLIENT FrogsClient(GAME_HOST,GAME_PORT,0);; //FrogsClient("127.0.0.1",8000,0);; //FrogsClient("localhost",8690,0); #endif //Game(&GameLevel0,GAMEF_DAY_CYCLE|GAMEF_CHAT_LOG); //Game(&AbortionSceneLevel); @,40ιP 5?1    KYTX: !U1 rZH= C: $wv5v<<{BBFKkHn574/>6@/H3I3NMD; 0771)C  =J @MDIE07!@&JFK;TDS;`H]  : + .[BG FJ=[ UJL\ [R Q [ W P# &-8EOGZ6O**+ - T<*<%3))))6; ? KfVOC .!' >JE=;10&%-H2] 4&@0@/@2 2= KW ("; ? KhiZC .' >JE=;10&%-H2]4&@0@/@2 2= KZ ( - CaG;2V:","  !!,.:   .A   )? *!0& 0F *= ("F<   :   !5  &@ "'! *D .3 ("9E   2 [;     Z:     A >)J.:6*6!  !  '  (   &FV ZN=(  E ] E! & "    : P >    3 X?4 oO"? t%6 - %    0  ?7G Q @# ) "! > c X E 5 /  I 3 R{W& R#GEP RS|/v>$ (@&$@8,73:8BHH7<QOJWWabeZZ<^:aX'YcWS H ?C=!B<DFCH;53 61 ;<%,^-3#T@ F6$j5IQƶ ۶[-E 5&  0$'3-0.#(  &#%, .# %#0 3  +* I Love Niggers   `!' a!~l/n<: 0ED)$3NP$'`&]7" ~ @ b5 g7g7D9s6 7}6$A?I u IڿI?IDamm6`ID$I$ymݶm۶ #" 8;7:# Semen Max(  2> 1  .K)LR@>0XI 74 (   #1 G @& *1 *   6<) )JOI[9N#9%2 V>6<03' L- @-% 5- /#To(frog->tongue,frog->looking_at_x,frog->looking_at_y); C2DObjectPointTo(frog->head,frog->looking_at_x,frog->looking_at_y); C2DObjectSetFlip(frog->head,0); C2DO#include "../_2d.HC"; #include "Speech.HC"; #define REG_SCORE "nroot/frogs/score" RegDft(REG_SCORE,"I64 high_score=0;;"); RegExe(REG_SCORE); #include "../UI.HC"; #include "../Eliza/Eliza.HC"; #include "../Server.HC" #define PREC1 precision 1 extern class CFrog; //FrogHead open $SP,"<1>",BI=1$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *frog_head_open=C2DObjectNewFromSprite($IB,"<1>",BI=1$); //Frog Head dead $SP,"<2>",BI=2$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *frog_head_dead=C2DObjectNewFromSprite($IB,"<2>",BI=2$); //FrogHead close $SP,"<3>",BI=3$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *frog_head_close=C2DObjectNewFromSprite($IB,"<3>",BI=3$); //Frog jump $SP,"<4>",BI=4$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *frog_jump=C2DObjectNewFromSprite($IB,"<4>",BI=4$); //Frog sit $SP,"<5>",BI=5$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *frog_sit=C2DObjectNewFromSprite($IB,"<5>",BI=5$); //Fly $SP,"<6>",BI=6$ C2DObject *fly1=C2DObjectNewFromSprite($IB,"<6>",BI=6$); //Fly2 $SP,"<7>",BI=7$ C2DObject *fly2=C2DObjectNewFromSprite($IB,"<7>",BI=7$); //Wasp1(6,9) $SP,"<8>",BI=8$ //123456789abcdef //1 //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *wasp1=C2DObjectNewFromSprite($IB,"<8>",BI=8$); //Wasp2() $SP,"<9>",BI=9$ //123456789abcdef //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *wasp2=C2DObjectNewFromSprite($IB,"<9>",BI=9$); //Background water $SP,"<10>",BI=10$ //1 //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *water=C2DObjectNewFromSprite($IB,"<10>",BI=10$); //Lily pad $SP,"<11>",BI=11$ //1 //2 //3 //4 //5 //6 //7 //8 //9 C2DObject *lily_pad=C2DObjectNewFromSprite($IB,"<11>",BI=11$); $SP,"<12>",BI=12$ // // // // $SP,"<13>",BI=13$ // // // // $SP,"<14>",BI=14$ class CShitSound2 { I64 duration,freq,lo,hi; F64 dampening; }; CTask *ShitSoundTask2(CShitSound2 *s) { music.mute++; F64 t=tS,e=t+ToF64(s->duration)/1000,cur=t; F64 next_dec=1./(s->freq)+t; for(;cur=next_dec) { next_dec=1./(s->freq)+cur; s->hi*=s->dampening; s->lo*=s->dampening; } Snd(s->lo+(s->hi-s->lo)*Caw(cur-t,1./s->freq)); Sleep(1); } Snd; music.mute--; } CTask *ShitSound2(I64 duration,I64 freq=20,I64 lo=47,I64 hi=27,F64 dampening=.9) { CShitSound2 *s=AMAlloc(sizeof CShitSound2); s->duration=duration,s->freq=freq,s->lo=lo,s->hi=hi; s->dampening=dampening; return Spawn(&ShitSoundTask2,s); } #define FLY_PATTERN_SINE 0 //Bezier #define FLY_PATTERN_BEZIER 1 //Line #define FLY_PATTERN_ZIP 2 //"Random" #define FLY_PATTERN_RANDOM 3 //CWasp Attacks a frog ->target //Wasps will spawn not angry,but when provoked will attack #define FLY_PATTERN_ATTACK 4 #define FLY_SINE_DIVIDE 60. #define FLY_ANIMATION_FREQ 10 // // CFly can refer to a wasp or a fly.(they both fly around) // fly_type will be FLYT_WASP for a wasp,and will use class CWasp(which has // type CWasp) class CFly:CServerThing { U0 (*destroy)(CFly *); C2DObject *body; #define FLYT_FLY 0 #define FLYT_WASP 1 I64 fly_type; F64 old_x PREC1,old_y PREC1; U0 pattern_info_start PREC1; F64 x PREC1,y PREC1,spawn_ts PREC1; //Animation cycle is a Sin and goes from 0 to 2*pi F64 spawn_x PREC1,spawn_y PREC1,animation_cycle PREC1; F64 origin_x PREC1,origin_y PREC1; //For Bezier F64 btarget_x PREC1,btarget_y PREC1; F64 end_x PREC1,end_y PREC1; F64 start_ts,sine_amplitude PREC1,speed; I64 pattern; I64 actions_until_leave; I64 actions_cnt; Bool done,pad[7]; }; class CWasp:CFly{ I64 state; CFrog *target swizzle; Bool is_angry,pad[7]; }; I64 GROUND_POSITION=GR_HEIGHT-8*7; #define TURD_CNT 64 #define TURD_GRAVITY 35 #define TURD_MELT_SPEED 3 class CTurd:CQue { C2DObject *turdg; F64 start_x PREC1,start_y PREC1,start_ts; F64 melt_percent; F64 xvelo PREC1,yvelo PREC1,start_angle; #define TURDS_PROJECTILE 1 //Turds will "melt" once the side of the arena #define TURDS_MELT 2 //Turd on the ground will sit until someone steps on them #define TURDS_GROUND 3 #define TURDS_STEPPED_ON 4 #define TURDS_DONE 5 I64 state; }; //All are F64 unless otherwise noted(Use FrogMovieMake to make // a movie and assign it to frog->user_data) #define FROG_MOVIE_JUMP 1 //Towards (x,y,velo) //Velo can be 0 for dft #define FROG_MOVIE_LOOK 2 //Towards (x,y,time) #define FROG_MOVIE_EAT 3 //Towards (x,y) #define FROG_MOVIE_STICK_OBJECT_TO_TONGUE 4 //At (x,y,C2DObject*) #define FROG_MOVIE_SHIT 5 //(Turds,duration) #define FROG_MOVIE_SLEEP 6 //Will sleep for (F64 seconds) #define FROG_MOVIE_DONE 7 //Will set ai_state[0] to FROG_MOVIE_DONE extern I64 *FrogMovieMake(...); extern U0 FrogAIMovieScene(CFrog *frog); extern U0 GameClear(); extern U0 TurdProjectileMove(CTurd *p); extern U0 ContinueAssBlast(CFrog *f); extern U0 InitAssBlastForFrog(CFrog *f,I64 turds,Bool propel=TRUE); extern U0 AssBlastFinish(CFrog *); U0 TurdProjectileDel(CTurd *p) { QueRem(p); if(p->turdg) C2DObjectDel(p->turdg); Free(p); } class CAssBlast { F64 freq,duration,start_ts,next_turd_ts; CQue turds; Bool propel_into_air,pad[7]; }; #define FROG_SHIT_VELOCITY 100 #define FROG_JUMP_VELOCITY 100 #define FROG_GRAVITY 35 #define FROG_DRAW_PRIORITY 3 #define FLY_DRAW_PRIORITY 128 #define TURD_DRAW_PRIORITY 1000 #define FROGF_PLAYER (1<<0) #define FROGF_CPU (1<<1) #define FROGF_MOUTH_OPEN (1<<2) #define FROGF_SITTING (1<<3) #define FROGF_DEAD (1<<4) #define FROGF_SHIT_FEET (1<<5) #define FROGF_SHITTING (1<<6) //This will cause the frogs tongue to go backwards #define FROGF_OBJECT_ON_TONGUE (1<<7) #define FROGF_SEMENMAX (1<<8) #define FROGF_LEAVE_STAGE (1<<10) //Will cause the frog to be a girlfreind frog(will benefit FROGF_SEMENMAX frog) #define FROGF_GIRLFREIND (1<<11) #define FROG_TONGUE_LENGTH 350 #define FROG_TONGUE_MIN_LENGTH 30 F64 FROG_TONGUE_DURATION=.300; #define FROG_DEATH_TIME 2 #define MAX_FROGS 8 class CFrog:CServerThing { U0 (*destroy)(CFrog *); F64 x,y; F64 jump_start_x PREC1,jump_start_y PREC1,jump_start_angle; F64 looking_at_x PREC1,looking_at_y PREC1,jump_start_ts; F64 yvelo,xvelo; //Tongue cycle is like a sine wave F64 tongue_length PREC1,tongue_start_ts; CFrog *boyfriend_frog swizzle; I64 fly_count,flies_since_last_shit; I64 flags; I64 priority,color,lives; //In our game,if we hit a frog in the air,we only hit once to //avoid infintiy bouncy frogs I64 hit_vector; C2DObject *head,*body,*tongue; //AI Aritifcial interlegnce,what controls the computer frogs U8 ai[32]; I64 user_data; I64 user_data2; F64 ai_param1; F64 ai_param2; F64 ai_param3; F64 ai_param4; F64 ai_param5; F64 ai_param6; F64 ai_state[16]; //Once a frog dies,it looses a life then it times out until death_penalty_wait_until F64 death_penalty_wait_until; //This is used for when you hit another frog,It will wait //for the collision to end before bouncing off the other frog again I64 hit_bitmap[1+MAX_FROGS/64]; C2DObject *object_on_tongue; F64 shit_feet_time; CAssBlast ass_blast; U8 *speech_text; F64 speech_end_ts,power_up_end_ts; //Optional //Used for the graphics of the frog C2DObject *reference_sit; C2DObject *reference_jump; C2DObject *reference_head_open; C2DObject *reference_head_close; C2DObject *reference_head_dead; CEliza *chat_bot_eliza; CTask *chat_bot_task; U8 name[32]; }; U0 FrogDel(CFrog *frog) { QueRem(frog); AssBlastFinish(frog); if(frog->head) C2DObjectDel(frog->head); if(frog->tongue) C2DObjectDel(frog->tongue); if(frog->body) C2DObjectDel(frog->body); if(frog->chat_bot_task) Kill(frog->chat_bot_task); Free(frog); } class CGame { F64 day_start; CServer *server; CTask *game_task,*sound_task,*day_task,*shit_sound_task; CFrog *player; C2DObject*sun,*moon; C2DWorld *world; I64 game_over,ms_x,ms_y; CBGR48 palette[16]; CUIChatLog *chat_log; CUITextBar *chat_bar; CQue ui_root; Bool done,chat_bar_active; } game; //Moves out of way of the mouse cursor U0 UpdateUIChatLogGr() { I64 w=GR_WIDTH/2; if(game.ms_xx=game.game_task->pix_width-w-4; game.chat_bar->x=game.game_task->pix_width-w; game.chat_log->y=0; } else { game.chat_log->x=4; game.chat_bar->x=0; game.chat_log->y=0; } game.chat_bar->y=game.chat_log->y+game.chat_log->sz_y+4; if(game.chat_bar_active) { game.chat_bar->fg_color=CYAN; game.chat_bar->bg_color=WHITE; game.chat_bar->border_color=LTGRAY; } else { game.chat_bar->fg_color=LTRED; game.chat_bar->bg_color=WHITE; game.chat_bar->border_color=BLACK; } } U0 UnFocusChatBar() { game.chat_bar_active=FALSE; UIUnFocus; UITextBarSetText(game.chat_bar,"Press 'T' to talk"); } U0 UIChatBarEnterCb(CUIElem *,U8 *str){ if(game.player) { UIChatLogAddLine(game.chat_log,"Player: ",str,game.player->color); } UnFocusChatBar; } U0 InitUI() { QueInit(&game.ui_root); game.chat_log=UIChatLogNew(GR_WIDTH/2.25/8,15,15); game.chat_log->bg_color=TRANSPARENT; game.chat_log->fg_color=LTRED; QueIns(game.chat_log,&game.ui_root); game.chat_bar=UITextBarNew("Press 'T' to talk",GR_WIDTH/2.25); game.chat_bar->fg_color=LTRED; game.chat_bar->bg_color=WHITE; game.chat_bar->border_color=BLACK; game.chat_bar->enter_cb=&UIChatBarEnterCb; QueIns(game.chat_bar,&game.ui_root); } class CPowerUp:CServerThing { U64 type; //is a char C2DObject *obj; U0 (*destroy)(CPowerUp*); U8 next_state[32]; }; #define POWER_UPT_SEMENMAX 'SemenMax' class CSemenMaxPowerUp:CPowerUp { F64 end_tS precision 30; F64 spawn_tS precision 30; F64 spawn_x,spawn_y; F64 direction; }; $SP,"<15>",BI=15$ //Girlfreind frog $SP,"<16>",BI=16$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 $SP,"<17>",BI=17$ //1234567890abcdef //2 //3 //4 //5 //6 //7 //8 //9 extern CFrog *MakeGirlfreindFrog(CFrog *for_frog); CFrog *GetBoyfriendFrog() { I64 cnt=FrogCnt; CFrog *cur; while(--cnt>=0) if((cur=FrogN(cnt))->flags&FROGF_SEMENMAX) return cur; return NULL; } U0 SemenMaxPowerUpNextState(CGame *g,CSemenMaxPowerUp *pu) { CFrog *frog; F64 state_time=tS-pu->spawn_tS; if(!pu->obj) { pu->obj=C2DObjectNewFromSprite($IB,"<15>",BI=15$,g->game_task); AddObjectToWorld(pu->obj,g->world); } pu->obj->x=pu->spawn_x+pu->direction*state_time*(GR_WIDTH/2.5); if(pu->obj->x<0) { pu->obj->x=0; pu->direction=1; pu->spawn_tS=tS; } else if(pu->obj->x>=GR_WIDTH) { pu->obj->x=GR_WIDTH; pu->spawn_tS=tS; pu->direction=-1; } pu->obj->y=pu->spawn_y+Sin(state_time*pi)*75; for(frog=game.frogs.next;frog!=&game.frogs;frog=frog->next) { if(C2DObjectCollisionTest(frog->tongue,pu->obj)) { frog->flags|=FROGF_SEMENMAX; frog->power_up_end_ts=tS+15; MakeGirlfreindFrog(frog); ServerThingDel(pu); return; } } } CPowerUp *SemenMaxNew() { CSemenMaxPowerUp *semen=ConstructThing(game.game_task,"CSemenMaxPowerUp"); semen->type=POWER_UPT_SEMENMAX; semen->spawn_tS=tS; if(Rand>.5) { semen->spawn_x=0; semen->direction=1; } else { semen->spawn_x=GR_WIDTH; semen->direction=-1; } semen->spawn_y=50; StrCpy(semen->next_state,"SemenMaxPowerUpNextState"); AddThingToServer(semen,game.server); return semen; } C2DWorld *world=C2DWorldNew(CYAN); U0 DrawFly(CFly *fly) { if(Blink(FLY_ANIMATION_FREQ)) { if(fly->body->user_data!=fly1){ C2DObjectSetGraphicsFromSprite(fly->body,fly1->sprite); fly->body->user_data=fly1; } } else { if(fly->body->user_data!=fly2){ C2DObjectSetGraphicsFromSprite(fly->body,fly2->sprite); fly->body->user_data=fly2; } } C2DObjectMove(fly->body,fly->x,fly->y); fly->body->priority=FLY_DRAW_PRIORITY+Rand*1000; //TODO improve } U0 DrawWasp(CWasp *wasp) { Bool flipped=FALSE; if(Blink(FLY_ANIMATION_FREQ)) { if(wasp->body->user_data!=wasp1){ C2DObjectSetGraphicsFromSprite(wasp->body,wasp1->sprite); C2DObjectMoveCenter(wasp->body,-6*8,9*8); wasp->body->user_data=wasp1; } } else { if(wasp->body->user_data!=wasp2){ C2DObjectSetGraphicsFromSprite(wasp->body,wasp2->sprite); C2DObjectMoveCenter(wasp->body,-6*8,9*8); wasp->body->user_data=wasp2; } } if(wasp->state==1||wasp->state==2) { if(wasp->x>wasp->end_x) flipped=TRUE; wasp->body->rot=Arg(wasp->end_x-wasp->x,wasp->end_y-wasp->y); } else { if(wasp->xold_x) flipped=TRUE; wasp->body->rot=Arg(wasp->x-wasp->old_x,wasp->y-wasp->old_y); } if(wasp->is_angry) { wasp->body->flags|=C2DOBJF_REPLACE_COLOR; wasp->body->with_color=RED; wasp->body->replace_color=YELLOW; } C2DObjectSetFlip(wasp->body,flipped); if(wasp->body->rot<0) wasp->body->rot+=2*pi; if(flipped) wasp->body->rot+=pi; C2DObjectMove(wasp->body,wasp->x,wasp->y); wasp->body->priority=FLY_DRAW_PRIORITY+Rand*1000; //TODO improove } U0 FlyDel(CFly *fly) { if(fly->body) C2DObjectDel(fly->body); Free(fly); } U0 FlyMove(CFly *fly) { F64 t=(Server_tS(game.server)-fly->start_ts)*fly->speed; fly->old_x=fly->x; fly->old_y=fly->y; switch(fly->pattern) { case FLY_PATTERN_SINE: fly->x=fly->spawn_x+t; fly->y=fly->spawn_y+fly->sine_amplitude*Sin(t/FLY_SINE_DIVIDE); //If fly is no longer visible,we go to poo poo land if(fly->body) if(fly->x-fly->body->width>=GR_WIDTH) fly->done=TRUE; break; case FLY_PATTERN_BEZIER: fly->x=fly->spawn_x*(1-t)`2+2.*(1-t)*t*fly->btarget_x+t*t*fly->end_x; fly->y=fly->spawn_y*(1-t)`2+2.*(1-t)*t*fly->btarget_y+t*t*fly->end_y; if(t>=1) goto init_rand; break; case FLY_PATTERN_ZIP: fly->x=fly->spawn_x+(fly->end_x-fly->spawn_x)*t; fly->y=fly->spawn_y+(fly->end_y-fly->spawn_y)*t; if(t>=1) goto init_rand; break; } return; init_rand: if(fly->fly_type==FLYT_WASP) fly->done=1; if(++fly->actions_cnt==fly->actions_until_leave) { fly->pattern=FLY_PATTERN_ZIP; fly->end_y=-100; fly->spawn_x=fly->x; fly->spawn_y=fly->y; fly->end_x=RandU64%GR_WIDTH; fly->start_ts=Server_tS(game.server); fly->speed=1; return; } else if(fly->actions_cnt>fly->actions_until_leave) { fly->done=1; } fly->start_ts=Server_tS(game.server); fly->pattern=FLY_PATTERN_ZIP; fly->spawn_x=fly->x; fly->spawn_y=fly->y; fly->end_y=RandU64%GROUND_POSITION; fly->end_x=RandU64%GR_WIDTH; fly->speed=0.5; } U0 WaspMove(CWasp *wasp) { F64 t=(Server_tS(game.server)-wasp->start_ts)*wasp->speed,tx,ty; I64 i,cnt; CFrog *f; wasp->old_x=wasp->x; wasp->old_y=wasp->y; switch(wasp->pattern) { break;case FLY_PATTERN_SINE: case FLY_PATTERN_BEZIER: case FLY_PATTERN_ZIP: normal: FlyMove(wasp); break; case FLY_PATTERN_ATTACK: if(t<1) { wasp->x=wasp->spawn_x+(wasp->btarget_x-wasp->spawn_x)*t; wasp->y=wasp->spawn_y+(wasp->btarget_y-wasp->spawn_y)*t; } else if(t<2) { if(!wasp->state) { wasp->state=1; cnt=FrogCnt; f=FrogN(RandU64%cnt); wasp->target=f; } else { wasp->end_x=GR_WIDTH/2-Sign(wasp->x-GR_WIDTH/2)*GR_WIDTH/2; wasp->end_y=GR_HEIGHT+100; wasp->spawn_x=wasp->x; wasp->spawn_y=wasp->y; //https://stackoverflow.com/questions/6711707/draw-a-quadratic-b%C3%A9zier-curve-through-three-given-points tx=wasp->target->body->x; ty=wasp->target->body->y; wasp->btarget_x=2*tx-wasp->spawn_x/2-wasp->end_x/2; wasp->btarget_y=2*ty-wasp->spawn_y/2-wasp->end_y/2; wasp->state=2; } } else if(t<4) { wasp->start_ts=Server_tS(game.server); //Reset the timestamp for the bezier; wasp->state=2; wasp->speed=0.3; wasp->pattern=FLY_PATTERN_BEZIER; goto normal; } } DrawWasp(wasp); //Update properyties } CFly *FlyNew(I64 pattern,F64 x,F64 y) { CFly *fly=ConstructThing(game.game_task,"CFly"); QueInit(fly); fly->destroy=&FlyDel; fly->start_ts=Server_tS(game.server); fly->speed=100; fly->fly_type=FLYT_FLY; fly->spawn_x=fly->x=x,fly->spawn_y=fly->y=y; fly->old_x=x,fly->old_y=y; fly->body=C2DObjectNewFromSprite(fly1->sprite,game.game_task); fly->pattern=pattern; switch(fly->pattern) { case FLY_PATTERN_SINE: fly->actions_until_leave=0; fly->sine_amplitude=175; break; case FLY_PATTERN_ZIP: fly->actions_until_leave=3; fly->end_x=RandU64%GR_WIDTH; fly->end_y=RandU64%(GROUND_POSITION-75); break; case FLY_PATTERN_BEZIER: fly->actions_until_leave=3; fly->btarget_x=RandU64%GR_WIDTH; fly->btarget_y=RandU64%(GROUND_POSITION-75); fly->end_x=RandU64%GR_WIDTH; fly->end_y=Rand%(GROUND_POSITION-75); break; } return fly; } CWasp *WaspNew(F64 x,F64 y) { CWasp *wasp=ConstructThing(game.game_task,"CWasp"); wasp->start_ts=Server_tS(game.server); wasp->speed=1; wasp->fly_type=FLYT_WASP; wasp->spawn_x=x,wasp->x=x,wasp->spawn_y=y,wasp->y=y; wasp->old_x=x,wasp->old_y=y; wasp->body=C2DObjectNewFromSprite(wasp1->sprite,game.game_task); wasp->pattern=FLY_PATTERN_ZIP; wasp->end_x=RandU64%GR_WIDTH; wasp->end_y=50+RandU64%150; wasp->actions_until_leave=5; return wasp; } U0 DrawFrog(CFrog *frog) { CDC *tongue_dc; if(frog->flags&FROGF_DEAD) { if(frog->head->user_data!=frog->reference_head_dead){ C2DObjectSetGraphicsFromSprite(frog->head,frog->reference_head_dead->sprite); frog->head->user_data=frog->reference_head_dead; frog->head->flags|=C2DOBJF_REPLACE_COLOR; frog->head->replace_color=GREEN; frog->head->with_color=frog->color; //Center for sitting body is at (0,0) C2DObjectMoveCenter(frog->body,0,0); } if(frog->body->user_data!=frog->reference_sit){ C2DObjectSetGraphicsFromSprite(frog->body,frog->reference_sit->sprite); frog->body->user_data=frog->reference_sit; frog->body->flags|=C2DOBJF_REPLACE_COLOR; frog->body->replace_color=GREEN; frog->body->with_color=frog->color; //Center for sitting body is at (0,5) C2DObjectMoveCenter(frog->body,0,8*5); } if(frog->looking_at_xx&&0) { C2DObjectMove(frog->head,frog->x-0xe*8,frog->y+1*8); C2DObjectMove(frog->body,frog->x,frog->y); C2DObjectSetFlip(frog->head,1); C2DObjectSetFlip(frog->body,0); C2DObjectRotate(frog->head,0); C2DObjectRotate(frog->body,pi); } else{ C2DObjectMove(frog->head,(frog->body->width)+frog->x,frog->y+1*8); C2DObjectMove(frog->body,frog->x,frog->y); C2DObjectSetFlip(frog->head,0); C2DObjectSetFlip(frog->body,1); C2DObjectRotate(frog->head,0); C2DObjectRotate(frog->body,pi); } tongue_dc=DCNew(1,1); C2DObjectSetGraphics(frog->tongue,tongue_dc); DCDel(tongue_dc); return; } frog->body->rot=0; if(frog->flags&FROGF_SITTING) { if(frog->body->user_data!=frog->reference_sit){ C2DObjectSetGraphicsFromSprite(frog->body,frog->reference_sit->sprite); frog->body->user_data=frog->reference_sit; frog->body->flags|=C2DOBJF_REPLACE_COLOR; frog->body->replace_color=GREEN; frog->body->with_color=frog->color; // DCColorChg(frog->body->graphics,GREEN,frog->color); } //Center for sitting body is at (0,5) C2DObjectMoveCenter(frog->body,0,8*5); } else { if(frog->body->user_data!=frog->reference_jump){ C2DObjectSetGraphicsFromSprite(frog->body,frog->reference_jump->sprite); frog->body->user_data=frog->reference_jump; frog->body->flags|=C2DOBJF_REPLACE_COLOR; frog->body->replace_color=GREEN; frog->body->with_color=frog->color; } //Center for jumping body is at (0,0) C2DObjectMoveCenter(frog->body,8*2,8*0x5); } if(frog->flags&FROGF_MOUTH_OPEN) { if(frog->head->user_data!=frog->reference_head_open){ C2DObjectSetGraphicsFromSprite(frog->head,frog->reference_head_open->sprite); frog->head->user_data=frog->reference_head_open; frog->head->flags|=C2DOBJF_REPLACE_COLOR; frog->head->replace_color=GREEN; frog->head->with_color=frog->color; } //Center for sitting body is at (0,5) C2DObjectMoveCenter(frog->head,0,8*5); //(0,1) tongue_dc=DCNew(frog->tongue_length,16); DCFill(tongue_dc,RED); tongue_dc->color=BLACK; GrRect(tongue_dc,0,4,tongue_dc->width,8); C2DObjectSetGraphics(frog->tongue,tongue_dc); DCDel(tongue_dc); C2DObjectMoveCenter(frog->tongue,0,4); } else { if(frog->head->user_data!=frog->reference_head_close){ C2DObjectSetGraphicsFromSprite(frog->head,frog->reference_head_close->sprite); frog->head->flags|=C2DOBJF_REPLACE_COLOR; frog->head->user_data=frog->reference_head_close; frog->head->replace_color=GREEN; frog->head->with_color=frog->color; } //Center for sitting body is at (0,5) C2DObjectMoveCenter(frog->head,0,5*8); tongue_dc=DCNew(1,1); C2DObjectSetGraphics(frog->tongue,tongue_dc); DCDel(tongue_dc); } frog->head->priority=FROG_DRAW_PRIORITY+10*frog->priority+2; frog->body->priority=FROG_DRAW_PRIORITY+10*frog->priority; frog->tongue->priority=FROG_DRAW_PRIORITY+10*frog->priority+1; //Move the frog head and body C2DObjectMove(frog->body,frog->x,frog->y); //If our frog is looking to the left reflect the head and body if(frog->looking_at_xx) { //Head is located at (0xf,2) //But we are reversed,so move the head towards frog->x C2DObjectMove(frog->head,(frog->body->width-0xe*8)+frog->x,frog->y-3*8); C2DObjectMove(frog->tongue,(frog->body->width-0xe*8)+frog->x,frog->y-3*8); //We are reversed,so move frog->body over // Forwards (x)---> // Backwars <---(x+width) C2DObjectMove(frog->body,frog->x+frog->body->width,frog->y); //roation will be "reversed" C2DObjectPointTo(frog->head,frog->looking_at_x,frog->looking_at_y); C2DObjectPointTo(frog->tongue,frog->looking_at_x,frog->looking_at_y); //Have same angle on opposite side of pole if(frog->head->rot<0) frog->head->rot+=2*pi; if(frog->head->flipped) frog->head->rot+=pi; C2DObjectSetFlip(frog->head,1); C2DObjectSetFlip(frog->body,1); } else { //Head is located at (0xe,2) C2DObjectMove(frog->head,frog->x+0xe*8,frog->y-3*8); if(frog->tongue) C2DObjectMove(frog->tongue,frog->x+0xe*8,frog->y-3*8); if(frog->tongue) C2DObjectPointTo(frog->tongue,frog->looking_at_x,frog->looking_at_y); C2DObjectPointTo(frog->head,frog->looking_at_x,frog->looking_at_y); C2DObjectSetFlip(frog->head,0); C2DObjectSetFlip(frog->body,0); } if(frog->flags&FROGF_OBJECT_ON_TONGUE&&frog->flags&FROGF_MOUTH_OPEN&&frog->object_on_tongue) { C2DObjectMoveCenter( frog->object_on_tongue, frog->object_on_tongue->width/2, frog->object_on_tongue->height/2 ); frog->object_on_tongue->y=frog->tongue_length*Sin(frog->tongue->rot)+frog->tongue->y; frog->object_on_tongue->x=frog->tongue_length*Cos(frog->tongue->rot)+frog->tongue->x; frog->object_on_tongue->priority=frog->tongue->priority+1; } else if(frog->object_on_tongue) { C2DObjectDel(frog->object_on_tongue); frog->object_on_tongue=NULL; } } U0 InitLilyPad() { // //frogs - 3<= //lily_pad 2 //water 1 lily_pad->priority=2; water->priority=1; AddObjectToWorld(lily_pad,game.world); AddObjectToWorld(water,game.world); //Now we need to position to lily pad and water in the world //Set the center of the lily_pad to the middle C2DObjectMoveCenter(lily_pad,lily_pad->width/2,lily_pad->height/2); C2DObjectMoveCenter(water,water->width/2,water->height/2); C2DObjectMove(lily_pad,GR_WIDTH/2,GR_HEIGHT-9*FONT_HEIGHT); C2DObjectScale(lily_pad,1.5); C2DObjectMove(water,GR_WIDTH/2,GR_HEIGHT-8*FONT_HEIGHT); } U0 Init() { game.game_task=Fs; InitUI; game.world=world; } #define SCOREBOARD_WIDTH 100 #define SCOREBOARD_HEIGHT 16 #define DAY_LENGTH 60 $SP,"<18>",BI=18$ $SP,"<19>",BI=19$ U0 DayCycleTask(CGame *game) { game->day_start=tS; static I64 sky_colors[5]={CYAN,LTBLUE,BLUE,DKGRAY,BLACK}; CDC*dummy; U8 *sprite; F64 cycle,sun_happiness=1,sun_angle,sun_cycle; game->sun=C2DObjectNewFromSprite($IB,"<18>",BI=18$,game->game_task); AddObjectToWorld(game->sun,game->world); for(;tS-game->day_startday_start)/DAY_LENGTH; switch(ToI64(cycle*5)) { //There are 5 cycles in 1 day start: game->world->background_color=sky_colors[ToI64(cycle*5)]; case 0: goto set_sun; break;case 1: goto set_sun; break;case 2: set_sun: //Sun lasts from 0<=<4 sun_cycle=(tS-game->day_start)/DAY_LENGTH*4; if(game->sun->user_data) Free(game->sun->user_data); sprite=SpriteInterpolate(Abs(Sin(tS)),$IB,"<18>",BI=18$,$IB,"<19>",BI=19$); C2DObjectSetGraphicsFromSprite(game->sun,sprite); game->sun->x=GR_WIDTH/2+(GR_WIDTH-200)/2*Cos(pi-sun_cycle*pi/2); game->sun->y=GR_HEIGHT-200+(GR_HEIGHT-200)*-Sin(pi-sun_cycle*pi/2); game->sun->user_data=sprite; break;case 3: break;case 4: end: } Sleep(100); } C2DObjectDel(game->sun); } U0 DrawIt(CTask *t,CDC *dc) { CServerThing *thing,*head; CFrog *cur_frog,*player=NULL; I64 cnt,idx,live; U8 *str; F64 x,y; head=&game.server->things; for(thing=head->next;thing!=head;thing=thing->next) { if(!StrCmp(thing->class_name,"CFrog")) DrawFrog(cur_frog); if(!StrCmp(thing->class_name,"CFly")) DrawFly(cur_frog); if(!StrCmp(thing->class_name,"CWasp")) DrawWasp(cur_frog); } //World needs to be updated with the screen that we are drawing too DrawWorld(t,game.world); GrBlot(dc,0,0,game.world->scrn); //Heres the deal,we still need to draw the frog speech bubbles for(thing=head->next;thing!=head;thing=thing->next) { if(!StrCmp(thing->class_name,"CFrog")) { cur_frog=thing; if(cur_frog->flags&FROGF_PLAYER) player=cur_frog; if(str=cur_frog->speech_text) { if(!cur_frog->head->flipped) { x=cur_frog->head->x+10*8; y=cur_frog->head->y-25; SpeechBubblePointTo(dc,str,x,y,x+100,y-75); } else { x=cur_frog->head->x-10*8; y=cur_frog->head->y-25; SpeechBubblePointTo(dc,str,x,y,x-100,y-75); } if(cur_frog->speech_end_tsspeech_text); cur_frog->speech_text=NULL; cur_frog->speech_end_ts=0; } } dc->color=GREEN; GrRect(dc,x=GR_WIDTH*ToF64(idx+1)/(cnt+1)-SCOREBOARD_WIDTH/2,y=GR_HEIGHT-3-SCOREBOARD_HEIGHT,SCOREBOARD_WIDTH,SCOREBOARD_HEIGHT); dc->color=RED; dc->thick=3; GrPrint(dc,x,y,"SCORE(%d):%d",idx,cur_frog->fly_count); for(live=0;livelives;live++) { dc->color=LTRED; dc->thick=6; GrPlot3(dc,x+live*8,y+FONT_HEIGHT/2+3,0); } } } if(game.game_over&&player&&Blink) { str=MStrPrint("Game Over(Score is %d)",player->fly_count); x=(GR_WIDTH-FONT_WIDTH*StrLen(str))/2; y=(GR_HEIGHT-FONT_HEIGHT/2)/2; GrPrint(dc,x,y,str); Free(str); str=MStrPrint("High Score is %d",high_score); x=(GR_WIDTH-FONT_WIDTH*StrLen(str))/2; y+=FONT_HEIGHT; GrPrint(dc,x,y,str); Free(str); } UpdateUIChatLogGr; RenderUI(dc,&game.ui_root,0,0,t->pix_width,t->pix_height); } U0 GameOver() { game.game_over=TRUE; if(game.player) { if(high_scorefly_count) RegWrite(REG_SCORE,"I64 high_score=%d;;\n",game.player->fly_count); } } U0 FrogBeginJump(CFrog *frog,F64 towards_x,F64 towards_y,F64 velo=FROG_JUMP_VELOCITY,Bool sound=FALSE) { if(frog->y>=GROUND_POSITION) frog->y=GROUND_POSITION-1; F64 x=towards_x-frog->x; F64 y=(frog->y-towards_y); if(sound) { Kill(game.sound_task); game.sound_task=Sweep(300,50,70); } F64 angle=Arg(x,y); F64 vh=velo*Sin(angle); F64 vx=velo*Cos(angle); frog->jump_start_x=frog->x; frog->jump_start_y=frog->y; frog->jump_start_angle=angle; frog->flags&=~FROGF_SITTING; frog->jump_start_ts=Server_tS(game.server); frog->yvelo+=vh; frog->xvelo+=vx; } U0 FrogContinueJump(CFrog *frog) { F64 x=(Server_tS(game.server)-frog->jump_start_ts),vh; if(!(frog->flags&FROGF_SITTING)) { frog->y-=frog->yvelo*x; frog->x+=frog->xvelo*x; frog->yvelo-=FROG_GRAVITY*x; if(!(frog->flags&FROGF_LEAVE_STAGE)) { if(frog->x<0) { frog->x=0; if(frog->xvelo<0) frog->xvelo*=-1; } if(frog->x>=GR_WIDTH) { frog->x=GR_WIDTH-1; if(frog->xvelo>0) frog->xvelo*=-1; } } } if(frog->y>=GROUND_POSITION) { frog->y=GROUND_POSITION; frog->yvelo=0; frog->xvelo=0; frog->flags|=FROGF_SITTING; MemSet(frog->hit_bitmap,0,1+MAX_FROGS/8); } } I64 FrogCnt() { I64 cnt; CServerThing *thing,*head=&game.server->things; for(thing=head->next;thing!=head;thing=thing->next) { if(!StrCmp(thing->class_name,"CFrog")) cnt++; } return cnt; } CFrog *FrogN(I64 n) { I64 cnt; CServerThing *thing,*head=&game.server->things; for(thing=head->next;thing!=head;thing=thing->next) { if(!StrCmp(thing->class_name,"CFrog")) if(--n<=0) return thing; } return NULL; } CFrog *AddFrog(I64 player=FALSE,F64 x=0,F64 y=GROUND_POSITION-1) { CDC *dc_dummy=DCNew(1,1); CFrog *new_frog=ConstructThing(game.game_task,"CFrog"); new_frog->destroy=&FrogDel; new_frog->x=x,new_frog->y=y; new_frog->flags=FROGF_SITTING; new_frog->looking_at_x=GR_WIDTH/2; new_frog->looking_at_y=GR_HEIGHT*3./4; new_frog->priority=FrogCnt; new_frog->ai_param1=0; new_frog->ai_param2=0; new_frog->ai_param3=0; new_frog->color=GREEN; new_frog->tongue=C2DObjectNewFromDC(dc_dummy,game.game_task); new_frog->body=C2DObjectNewFromDC(dc_dummy,game.game_task); new_frog->head=C2DObjectNewFromDC(dc_dummy,game.game_task); new_frog->lives=3; new_frog->reference_head_open=frog_head_open; new_frog->reference_head_close=frog_head_close; new_frog->reference_head_dead=frog_head_dead; new_frog->reference_jump=frog_jump; new_frog->reference_sit=frog_sit; AddObjectToWorld(new_frog->tongue,game.world); AddObjectToWorld(new_frog->body,game.world); AddObjectToWorld(new_frog->head,game.world); AddThingToServer(new_frog,game.server); return new_frog; } //Returns the player that is doing the best(except for the current frog) CFrog *BestPlayer(CFrog *frog) { CFrog *frog2,*best_frog=frog; I64 cnt=FrogCnt; while(--cnt>=0) if((frog2=FrogN(cnt))->fly_count>=best_frog->fly_cnt) best_frog=frog2; return best_frog; } CFly *ClosestFly(CFrog *frog) { CFly *fly=game.flies.next,*best_fly=NULL; F64 best_dist=F64_MAX,dist; for(;fly!=&game.flies;fly=fly->next) { switch(fly->fly_type) { break;case FLYT_FLY: dist=Sqrt((fly->x-frog->x)`2+(fly->y-frog->y)`2); if(best_dist>dist) { best_dist=dist; best_fly=fly; } } } return best_fly; } F64 AngleDiff(F64 a,F64 b) { if(a<0) a=2*pi-a; if(b<0) b=2*pi-b; if(a>b) return a-b; return b-a; } #define AI_ANGRY_WASP_IGNORE_RADIUS 100 #define AI_ANGRY_WASP_IGNORE_FORCE 125 #define AI_FLY_CLUMP_RADIUS 50 #define AI_FLY_PER_ASS_BLAST 4 #define AI_MINIMUM_ASS_BLAST_FLIES 3 #define AI_WASP_DANGER_ZONE 85 #define AI_JUMP_DIST (GR_WIDTH/2) //Find the amount of flies that are "clump"ed toghter // This is used by the AI to tell which cluster/"swarm" to chase I64 FlyClumpCnt(CFly *fly) { I64 clump=0; F64 x,y; CFly *cur,*head=&game.flies; for(cur=head->next;cur!=head;cur=cur->next) { if(cur->fly_type==FLYT_FLY) { x=fly->body->x-cur->body->x; y=fly->body->y-cur->body->y; if(Sqrt(Sqr(x)+Sqr(y))<=AI_FLY_CLUMP_RADIUS) { clump++; } } } return clump; } F64 PushBackDist(F64 x,F64 y,F64 x2,F64 y2,F64 radius,F64 force) { F64 dist=Sqrt(Sqr(x2-x)+Sqr(y2-y)); if(dist>radius) return 0; return (radius-dist)*force; } I64 *FrogMovieMake(...) { F64 *ret=MAlloc((argc+1)*sizeof(I64)); I64 idx; for(idx=0;idxuser_data) return; //ai_state[0] is the current state(0 if looking for a new state) //ai_state[1] is the state end_time F64 *state=frog->user_data,x,y,velo,time; state+=frog->user_data2; if(frog->ai_state[0]==FROG_MOVIE_LOOK) { x=state[1]; y=state[2]; time=Server_tS(game.server)-frog->ai_state[1]; x=(x-frog->ai_state[2])*(time/state[3])+frog->ai_state[2]; y=(y-frog->ai_state[3])*(time/state[3])+frog->ai_state[3]; frog->looking_at_x=x; frog->looking_at_y=y; if(time>state[3]) { frog->user_data2+=4; //(state,x,y,velo) frog->ai_state[0]=0; return; } else return; } else if(frog->ai_state[0]==FROG_MOVIE_JUMP){ if(!(frog->flags&FROGF_SITTING)) return; frog->user_data2+=4; //(state,x,y,velo) frog->ai_state[0]=0; return; } else if(frog->ai_state[0]==FROG_MOVIE_STICK_OBJECT_TO_TONGUE) { time=(Server_tS(game.server)-frog->ai_state[1])/FROG_TONGUE_DURATION; if(pi>time>pi/2) { if(frog->object_on_tongue) C2DObjectDel(frog->object_on_tongue); frog->object_on_tongue=C2DObjectCopy(state[3](I64),game.game_task); AddObjectToWorld(frog->object_on_tongue,game.world); frog->flags|=FROGF_OBJECT_ON_TONGUE; return; } else if(timeobject_on_tongue) C2DObjectDel(frog->object_on_tongue); frog->object_on_tongue=NULL; return; } frog->user_data2+=4; //(state,x,y,2d-object) frog->ai_state[0]=0; return; } else if(frog->ai_state[0]==FROG_MOVIE_EAT) { time=(Server_tS(game.server)-frog->ai_state[1])/FROG_TONGUE_DURATION; if(timeuser_data2+=3; //(state,x,y) frog->ai_state[0]=0; } else if(frog->ai_state[0]==FROG_MOVIE_SHIT) { if(Server_tS(game.server)ai_state[1]) return; frog->user_data2+=3; //(state,turds,duration) frog->ai_state[0]=0; return; }else if(frog->ai_state[0]==FROG_MOVIE_SLEEP) { if(Server_tS(game.server)ai_state[1]) return; frog->user_data2+=2; //(state,duration) frog->ai_state[0]=0; return; } switch(state[0](I64)) { break;case 0: Free(frog->user_data); frog->user_data=NULL; break;case FROG_MOVIE_JUMP: x=state[1],y=state[2],velo=state[3]; if(velo==0) velo=FROG_JUMP_VELOCITY; frog->looking_at_x=x; frog->looking_at_y=y; FrogBeginJump(frog,x,y,velo,TRUE); frog->ai_state[0]=FROG_MOVIE_JUMP; break;case FROG_MOVIE_LOOK: x=state[1],y=state[2],time=state[3]; frog->ai_state[0]=FROG_MOVIE_LOOK; frog->ai_state[1]=Server_tS(game.server); frog->ai_state[2]=frog->looking_at_x; frog->ai_state[3]=frog->looking_at_y; break;case FROG_MOVIE_EAT: x=state[1],y=state[2]; frog->looking_at_x=x; frog->looking_at_y=y; frog->ai_state[0]=FROG_MOVIE_EAT; frog->ai_state[1]=Server_tS(game.server); frog->flags|=FROGF_MOUTH_OPEN; frog->tongue_start_ts=Server_tS(game.server); break;case FROG_MOVIE_STICK_OBJECT_TO_TONGUE: x=state[1],y=state[2]; frog->looking_at_x=x; frog->looking_at_y=y; frog->ai_state[0]=FROG_MOVIE_STICK_OBJECT_TO_TONGUE; frog->ai_state[1]=Server_tS(game.server); frog->flags|=FROGF_MOUTH_OPEN; frog->tongue_start_ts=Server_tS(game.server); break;case FROG_MOVIE_SHIT: InitAssBlastForFrog(frog,state[1]); frog->ai_state[1]=Server_tS(game.server)+state[2]; frog->ai_state[0]=FROG_MOVIE_SHIT; break;case FROG_MOVIE_SLEEP: frog->ai_state[1]=Server_tS(game.server)+state[1]; frog->ai_state[0]=FROG_MOVIE_SLEEP; break;case FROG_MOVIE_DONE: frog->ai_state[0]=FROG_MOVIE_DONE; } } U0 FrogAI0(CFrog *frog) { CFrog *best; //ai_param1 is tongue timeout //ai_state[0] is last tongue time Bool wants_jump=FALSE,wants_tongue=FALSE; F64 force,angle; I64 state=frog->ai_state[0]; CFly *cur_f,*head_f=game.flies,*best_clus_fly=NULL; I64 best_clus=0; for(cur_f=head_f->next;cur_f!=head_f;cur_f=cur_f->next) { if(cur_f->fly_type==FLYT_FLY) if(best_cluslooking_at_x=best->body->x; frog->looking_at_y=best->body->y-50; wants_jump=TRUE; wants_tongue=TRUE; } else if(!(frog->flags&FROGF_SHITTING)) if(AI_MINIMUM_ASS_BLAST_FLIES<=frog->flies_since_last_shit) if(best_clus*AI_FLY_PER_ASS_BLAST>3*frog->flies_since_last_shit) { ass_blast_for_flies: InitAssBlastForFrog(frog,3*frog->flies_since_last_shit); goto chase_fly; } chase_fly: if(best_clus_fly) { frog->looking_at_x=best_clus_fly->body->x; frog->looking_at_y=best_clus_fly->body->y; wants_jump=TRUE; wants_tongue=TRUE; avoid_wasps: for(cur_f=head_f->next;cur_f!=head_f;cur_f=cur_f->next) { if(cur_f->fly_type==FLYT_WASP) { if(cur_f(CWasp*)->is_angry) if(force=PushBackDist(frog->looking_at_x,frog->looking_at_y,cur_f->body->x, cur_f->body->y,AI_ANGRY_WASP_IGNORE_RADIUS, AI_ANGRY_WASP_IGNORE_FORCE)) { angle=Arg(cur_f->body->x-frog->looking_at_x,cur_f->body->y-frog->looking_at_y); frog->looking_at_x=cur_f->body->x+force*Sin(angle); frog->looking_at_y=cur_f->body->y+force*Cos(angle); } } } } close_to_angry_wasp: for(cur_f=head_f->next;cur_f!=head_f;cur_f=cur_f->next) { if(cur_f->fly_type==FLYT_WASP) { if(cur_f(CWasp*)->is_angry) { if(force=PushBackDist(frog->y,frog->x,cur_f->body->x, cur_f->body->y,AI_ANGRY_WASP_IGNORE_RADIUS/2, AI_ANGRY_WASP_IGNORE_FORCE/2)) { frog->looking_at_x=frog->x; frog->looking_at_y=frog->y; angle=Arg(cur_f->body->x-frog->looking_at_x,cur_f->body->y-frog->looking_at_y); frog->looking_at_x=cur_f->body->x+force*Sin(angle); frog->looking_at_y=cur_f->body->y+force*Cos(angle); if(frog->looking_at_y>GROUND_POSITION) frog->looking_at_y=GROUND_POSITION-20; wants_jump=TRUE; wants_tongue=FALSE; } } } } if(wants_tongue&&!(frog->flags&FROGF_MOUTH_OPEN)&&frog->ai_state[0]<=tS) { frog->ai_state[0]=Server_tS(game.server)+frog->ai_param1; frog->flags|=FROGF_MOUTH_OPEN; frog->tongue_length=FROG_TONGUE_MIN_LENGTH; frog->tongue_start_ts=Server_tS(game.server); } if(wants_jump) if((frog->flags&FROGF_SITTING)&&!(frog->flags&FROGF_SHITTING)) FrogBeginJump(frog,frog->looking_at_x,frog->looking_at_y,,TRUE); } U8 *RandSub(U8 *str) { I64 cnt=0; while(LstSub(cnt,str)) cnt++; if(!cnt--) return; cnt=RandU64%cnt; return LstSub(cnt,str); } #define FROG_TALK_WINNING "winning" #define FROG_TALK_LOOSING "loosing" #define FROG_TALK_FLY "fly" #define FROG_TALK_WASP "wasp" U0 FrogAI1Talk(CFrog *frog,U8 *flag) { if(TaskValidate(frog->chat_bot_task)) { FramePtrDel(FROG_TALK_WINNING,frog->chat_bot_task); FramePtrDel(FROG_TALK_LOOSING,frog->chat_bot_task); FramePtrDel(FROG_TALK_FLY,frog->chat_bot_task); FramePtrDel(FROG_TALK_WASP,frog->chat_bot_task); FramePtrAdd(flag,1,frog->chat_bot_task); } } U8 *ChatBotGetStr(CEliza *f) { //Todo text input from player CFrog *frog=f->user_data(CFrog*); CUIChatLogLine *ln; if(frog->speech_end_ts) Sleep((frog->speech_end_ts-tS)*1000); Sleep(Rand*1500+500); for(ln=game.chat_log->lines.last;ln!=&game.chat_log->lines;ln=ln->last) { //Ignore ": " if(StrNCmp(ln->name,frog->name,StrLen(frog->name))) if(ln->num>FramePtr("last_proc_chat_line")) { FramePtrSet("last_proc_chat_line",ln->num); return StrNew(ln->text); } } return StrNew(""); } U0 ChatBotDispStr(CEliza *f,U8 *str) { CFrog *frog=f->user_data; U8 *str2=MStrPrint("%s: ",frog->name); I64 use_color=frog->color; //Birghter version of colors are in low+8; if(use_color<8) use_color+=8; str=MStrUtil(str,SUF_REM_CTRL_CHARS); if(frog->speech_text) Free(frog->speech_text); frog->speech_text=StrNew(str,game.game_task); frog->speech_end_ts=tS+2; UIChatLogAddLine(game.chat_log,str2,str,use_color); Free(str),Free(str2); } CTask *Frog1ChatBot(CFrog *frog) { U8 *data=FileRead("Frog1.TXT"); frog->chat_bot_eliza=ElizaNew(data); frog->chat_bot_eliza->user_data=frog; frog->chat_bot_eliza->get_str=&ChatBotGetStr; frog->chat_bot_eliza->disp_str=&ChatBotDispStr; frog->chat_bot_task=Fs; StrCpy(frog->name,"Frog1"); Free(data); FramePtrAdd("last_proc_chat_line",0); ElizaChat(frog->chat_bot_eliza); } //The dumb frog,choose the closest fly and jump away U0 FrogAI1(CFrog *frog) { if(!frog->chat_bot_task) { frog->chat_bot_task=Spawn(&Frog1ChatBot,frog,"FrogAI1Chat",,game.game_task); } CFrog *best=BestPlayer(frog); CFly *fly=ClosestFly(frog); CWasp *wasp; F64 angle1,angle2,dist; Bool is_winning=TRUE,tried_fly=FALSE; U8 *data; if(best) is_winning=best->fly_countfly_count; if(frog->flags&FROGF_SHITTING&&fly) goto chase_fly; if(!frog->ai_state[1]) frog->ai_state[1]=tS; //ai_param1 is the maximum waiting time before next action //ai_param2 is percentage of time frog pesters best player //ai_param3 is jump_vecoity for pestering player //ai_param4 is the "mouse" move speed(Percent of desired location per frame) //ai_param5 is ass-blast probability when loosing //ai_param6 is ass-blast probability when winning //ai_state[0] is expected wait time. //ai_state[1] is time since last action. if(frog->ai_state[0]<=Server_tS(game.server)-frog->ai_state[1]) { if(frog->flags&FROGF_SITTING) { if(Randai_param2) goto pester_player; } chase_fly: tried_fly=TRUE; if(fly) { //Check to attempt to look away from a wasp angle1=Arg(frog->looking_at_x-frog->x,frog->looking_at_x-frog->y); for(wasp=game.flies.next;wasp!=&game.flies;wasp=wasp->next) { switch(wasp->fly_type) { break;case FLYT_WASP: if(wasp->is_angry&&wasp->body) { FrogAI1Talk(frog,FROG_TALK_WASP); angle2=Arg(wasp->body->x-frog->x,wasp->body->y-frog->y); if(AngleDiff(angle1,angle2)looking_at_x=fly->x; frog->looking_at_y=fly->y; FrogAI1Talk(frog,FROG_TALK_FLY); if(!(frog->flags&FROGF_SHITTING)) { if(frog->flies_since_last_shit>3&&is_winning&&Randai_param5) { ass_blast: InitAssBlastForFrog(frog,3*frog->flies_since_last_shit); frog->flies_since_last_shit=0; return; } if(frog->flies_since_last_shit&&!is_winning&&Randai_param6) goto ass_blast; } done_look_at: angle1=Arg(frog->looking_at_x-frog->x,frog->looking_at_x-frog->y); dist=Sqrt(Sqr(frog->looking_at_x-frog->x)+Sqr(frog->looking_at_y-frog->y)) //ai_param4 is the percept per frame *Clamp(frog->ai_param4*(Server_tS(game.server)-frog->ai_state[0])/WINMGR_PERIOD,0,1); frog->looking_at_x=dist*Cos(angle1)+frog->x; frog->looking_at_y=dist*Sin(angle1)+frog->y; if(frog->flags&FROGF_SITTING) { frog->flags|=FROGF_MOUTH_OPEN; frog->tongue_length=FROG_TONGUE_MIN_LENGTH; frog->tongue_start_ts=Server_tS(game.server); FrogBeginJump(frog,frog->looking_at_x,frog->looking_at_y,,TRUE); goto competed_action; } } else { pester_player: if(is_winning) FrogAI1Talk(frog,FROG_TALK_WINNING); else FrogAI1Talk(frog,FROG_TALK_LOOSING); if(best!=frog) { //If we need flies,look for flies and not pester player if(fly&&frog->fly_countfly_count&&!tried_fly) { goto chase_fly; } frog->looking_at_x=best->x; //Jump above player frog as we are either sitting or jumping frog->looking_at_y=best->y-200; if(frog->flags&FROGF_SITTING) { frog->flags|=FROGF_MOUTH_OPEN; frog->tongue_length=FROG_TONGUE_MIN_LENGTH; frog->tongue_start_ts=Server_tS(game.server); FrogBeginJump(frog,frog->looking_at_x,frog->looking_at_y,frog->ai_param3,TRUE); competed_action: frog->ai_state[0]=Rand*frog->ai_param1; frog->ai_state[1]=Server_tS(game.server); } } } } } U0 GameWaitForClearWave() { while(QueCnt(&game.flies)){ Sleep(100); } } U0 FrogCloseMouth(CFrog *frog,C2DObject *obj=NULL) { F64 tongue_cycle,dist,angle; if(obj) { if(frog->object_on_tongue) C2DObjectDel(frog->object_on_tongue); frog->object_on_tongue=C2DObjectCopy(obj); frog->flags|=FROGF_OBJECT_ON_TONGUE; if(tongue_cyclex-frog->tongue->x)+Sqr(obj->y-frog->tongue->y)); tongue_cycle=(ASin((FROG_TONGUE_LENGTH-FROG_TONGUE_MIN_LENGTH)/dist)+pi/2)*FROG_TONGUE_DURATION; //frog->tongue_start_ts+=tongue_cycle-frog->tongue_start_ts; frog->flags|=FROGF_OBJECT_ON_TONGUE; AddObjectToWorld(frog->object_on_tongue,game.world); } } else frog->flags&=~(FROGF_MOUTH_OPEN|FROGF_OBJECT_ON_TONGUE); } class CFlyWave { CFly *fly; I64 rep_cnt; I64 spacing; }; CTask *FlyWaveTask(CFlyWave *fw) { CFly *fly=fw->fly; I64 rep_cnt=fw->rep_cnt,time_spacing=fw->spacing; I64 idx; CFly *new; if(rep_cnt) { for(idx=0;idx!=rep_cnt;idx++) { new=FlyNew(fly->pattern,fly->x,fly->y); MemCpy(&new->pattern_info_start,&fly->pattern_info_start,sizeof(CFly) -offset(CFly.pattern_info_start)); new->start_ts=Server_tS(game.server); DrawFly(new); //Set properties AddObjectToWorld(new->body,game.world); QueInit(new); QueIns(new,game.flies.last); Sleep(time_spacing); } } Free(fw); } CTask *GameCreateWaveFromFly(CFly *fly,I64 rep_cnt,I64 spacing) { CFlyWave *fw=CAlloc(sizeof(CFlyWave),game.game_task); fw->fly=fly; fw->rep_cnt=rep_cnt; fw->spacing=spacing; return Spawn(&FlyWaveTask,fw); } class CWaspWave { I64 rep_cnt; I64 time_spacing; }; U0 WaspWaveTask(CWaspWave *data) { I64 rep_cnt=data->rep_cnt,time_spacing=data->time_spacing; I64 idx; CWasp *wasp; if(rep_cnt) { for(idx=0;idx!=rep_cnt;idx++) { wasp=WaspNew(RandU64%GR_WIDTH,50+100%RandU64); wasp->start_ts=Server_tS(game.server); DrawWasp(wasp); //Set properties AddObjectToWorld(wasp->body,game.world); QueInit(wasp); QueIns(wasp,game.flies.last); Sleep(time_spacing); } } Free(data); } CTask *GameCreateWaspWave(I64 rep_cnt,I64 spacing) { CWaspWave *ww=CAlloc(sizeof(CWaspWave),game.game_task); ww->rep_cnt=rep_cnt; ww->time_spacing=spacing; return Spawn(&WaspWaveTask,ww); } U0 FrogDie(CFrog *frog) { Sweep(200,50,45); frog->flags|=FROGF_DEAD; frog->death_penalty_wait_until=Server_tS(game.server)+FROG_DEATH_TIME; } U0 GameLevel0(I64 d) { //TODO startup music CTask *fly_wave,*wasp_wave; InitLilyPad; CFly *template; CFrog *cpu=AddFrog(FALSE,400); cpu->color=RED; StrCpy(cpu->ai,"FrogAI1"); // cpu->ai=&FrogAIMovieScene; cpu->user_data=FrogMovieMake( FROG_MOVIE_JUMP,100.,0.,1., FROG_MOVIE_LOOK,1,300.,1., FROG_MOVIE_EAT,10.,10., FROG_MOVIE_SLEEP,1., FROG_MOVIE_EAT,640.,30., FROG_MOVIE_SHIT,15. ); cpu->ai_param1=.75; cpu->ai_param2=0.75; cpu->ai_param3=FROG_JUMP_VELOCITY*.75; cpu->ai_param4=1; cpu->ai_param5=.5; cpu->ai_param6=.25; //Wave 1 template=FlyNew(FLY_PATTERN_SINE,0,100); fly_wave=GameCreateWaveFromFly(template,10,100); wasp_wave=GameCreateWaspWave(1,1000/3); DeathWait(&fly_wave); DeathWait(&wasp_wave); GameWaitForClearWave; //Wave 2 ServerThingDel(template); SemenMaxNew; template=FlyNew(FLY_PATTERN_BEZIER,0,100); template->speed=0.5; template->end_x=GR_WIDTH; template->end_y=100; template->btarget_x=GR_WIDTH/2; template->btarget_y=GROUND_POSITION; fly_wave=GameCreateWaveFromFly(template,10,100); wasp_wave=GameCreateWaspWave(1,1000/3); DeathWait(&fly_wave); DeathWait(&wasp_wave); GameWaitForClearWave; ServerThingDel(template); //Wave 3 template=FlyNew(FLY_PATTERN_SINE,GR_WIDTH,100); template->speed*=-1; fly_wave=GameCreateWaveFromFly(template,10,100); wasp_wave=GameCreateWaspWave(2,1000/5); DeathWait(&fly_wave); DeathWait(&wasp_wave); GameWaitForClearWave; ServerThingDel(template); } //Vagina $SP,"<20>",BI=20$ //123456789abcdef12345678 //2 //3 //4 //5 //6 //7 //8 //Abortion table $SP,"<21>",BI=21$ //Fetus $SP,"<22>",BI=22$ U0 AbortionSceneLevel(I64) { GameClear; I64 old_world=game.world,old_gp=GROUND_POSITION,old_t=FROG_TONGUE_DURATION; GROUND_POSITION=350; FROG_TONGUE_DURATION=.5; CFrog *frog=AddFrog(FALSE,0,GROUND_POSITION); StrCpy(frog->ai,"FrogAIMovieScene"); frog->x=0,frog->y=GROUND_POSITION; C2DObject *table=C2DObjectNewFromSprite($IB,"<21>",BI=21$,game.game_task); C2DObject *pussy=C2DObjectNewFromSprite($IB,"<20>",BI=20$,game.game_task); C2DObject *fetus=C2DObjectNewFromSprite($IB,"<22>",BI=22$,game.game_task); C2DObjectMoveCenter(table,0,0); C2DObjectMoveCenter(pussy,0,0); frog->user_data=FrogMovieMake( FROG_MOVIE_JUMP,ToF64(8*0x18),ToF64(GROUND_POSITION-8*0x18),50., FROG_MOVIE_LOOK,ToF64(516),ToF64(GROUND_POSITION-20),.3, FROG_MOVIE_STICK_OBJECT_TO_TONGUE,ToF64(516),ToF64(GROUND_POSITION-20),fetus, FROG_MOVIE_SLEEP,.75, FROG_MOVIE_LOOK,ToF64(GR_WIDTH*.75),ToF64(GR_HEIGHT/2),.1, FROG_MOVIE_SHIT,50. ); pussy->x=0x18*8; pussy->priority=frog->body->priority-1; table->priority=frog->body->priority-2; pussy->y=GROUND_POSITION-8*8; table->y=GROUND_POSITION; table->x=0; AddObjectToWorld(pussy,game.world); AddObjectToWorld(table,game.world); while(frog->ai_state[0]!=FROG_MOVIE_DONE) Sleep(100); C2DObjectDel(table); C2DObjectDel(pussy); C2DObjectDel(fetus); C2DWorldDel(game.world); FROG_TONGUE_DURATION=old_t; GROUND_POSITION=old_gp; } // // Server Message Section // CFrog *_GetPlayerFrog(CServer *s) { I64 id=FramePtr("PLAYER_FROG"); CFrog *f; if(f=ServerId2Ptr(s,id)) if(!StrCmp(f->class_name,"CFrog")) return f; return NULL; } U0 Message_PlayerJoin(CServer *s,CMessagePass *pass) { //TODO which client CD2I64 *ud=pass->body; CFrog *f=AddFrog(TRUE,ud->x,ud->y); AddThingToServer(f,s); FramePtrAdd("PLAYER_FROG",f->id); } U0 Message_LookAt(CServer *s,CMessagePass *pass) { CFrog *f=_GetPlayerFrog(s); CD2I64 *ud=pass->body; if(!f) return; f->looking_at_x=ud->x; f->looking_at_y=ud->y; } U0 Message_JumpTowards(CServer *s,CMessagePass *pass) { CFrog *f=_GetPlayerFrog(s); if(!f) return; if(f->flags&FROGF_SITTING) FrogBeginJump(f,f->looking_at_x,f->looking_at_y,,TRUE); if(!(f->flags&FROGF_MOUTH_OPEN)) { f->flags|=FROGF_MOUTH_OPEN; f->tongue_length=FROG_TONGUE_MIN_LENGTH; f->tongue_start_ts=Server_tS(game.server); } } U0 Message_AssBlast(CServer *s,CMessagePass *pass) { CFrog *f=_GetPlayerFrog(s); if(!f) return; //Create an ass blast based on how many flies you ate if(f->flies_since_last_shit&&!(f->flags&FROGF_SHITTING)) InitAssBlastForFrog(a,3*f->flies_since_last_shit); } // // Client section // #define GAMEF_DAY_CYCLE 1 #define GAMEF_CHAT_LOG 2 U0 FrogsClient(U8 *host,I64 port,I64 game_flags) { CServer *client=ClientNew(host,port); I64 msg,arga,argb; CD2I64 pair; SettingsPush; WinMax; WinBorder; DocClear; AutoComplete; Fs->draw_it=&DrawIt; game.game_task=Fs; game.world=world; game.done=FALSE; if(flags&GAMEF_DAY_CYCLE) game.day_task=Spawn(&DayCycleTask,&game,"Day",,Fs); ClientPassMessage(client,"Message_PlayerJoin",1,0); while(!game.done) { if(MSG_MS_MOVE==(msg=ScanMsg(&arga,&argb,1<draw_it=&DrawIt; game.game_task=Fs; game.world=world; game.done=FALSE; CServerThing *thing,*head; CD2I64 hit_at; I64 arga,argb,msg; F64 x,y,angle; F64 tongue_cycle; CFrog *frog1,*frog2; CFly *fly1,*fly2; CTask *level,*day; level=Spawn(level_task,&game,"Level",,Fs); if(flags&GAMEF_DAY_CYCLE) game.day_task=Spawn(&DayCycleTask,&game,"Day",,Fs); BirthWait(&level); head=&server->things; for(thing=head->next;thing!=head;thing=thing->next) { if(ThingHasClass("CPowerUp",thing)) CallExtStr(thing(CPowerUp*)->next_state,power_up); else if(ThingHasClass("CFrog",thing)) { if(frog1->flags&FROGF_DEAD) { if(Server_tS(game.server)>=frog1->death_penalty_wait_until) { if(--frog1->lives<=0) { if(a==frog1) { game.game_over=TRUE; } else { ServerThingDel(frog1); } } else { frog1->flags&=~FROGF_DEAD; } } } } for(fly1=game.flies.next;fly1!=&game.flies;) { if(fly1->done) { fly2=fly1->next; ServerThingDel(fly1); fly1=fly2; } else{ if(fly1->fly_type==FLYT_FLY) FlyMove(fly1); else if(fly1->fly_type==FLYT_WASP) WaspMove(fly1); } fly1=fly1->next; } for(frog1=game.frogs.next;frog1!=&game.frogs;frog1=frog1->next) { if(frog1->flags&FROGF_MOUTH_OPEN) { tongue_cycle=(Server_tS(game.server)-frog1->tongue_start_ts)/FROG_TONGUE_DURATION; if(tongue_cycle>pi) FrogCloseMouth(frog1); frog1->tongue_length=(FROG_TONGUE_LENGTH-FROG_TONGUE_MIN_LENGTH)*Sin(tongue_cycle)+FROG_TONGUE_MIN_LENGTH; } } for(frog1=game.frogs.next;frog1!=&game.frogs;frog1=frog2) { frog2=frog1->next; if(frog1->flags&FROGF_SEMENMAX) { if(frog1->power_up_end_tsflags&=~FROGF_SEMENMAX; } } if(frog1->ai&&!(frog1->flags&FROGF_DEAD)) (*frog1->ai)(frog1); FrogContinueJump(frog1); ContinueAssBlast(frog1); if(frog1->tongue&&!(frog1->flags&FROGF_DEAD)) { for(fly1=game.flies.next;fly1!=&game.flies;) { if(fly1->body) { if(C2DObjectCollisionTest(frog1->tongue,fly1->body)) { switch(fly1->fly_type) { break;case FLYT_FLY: //Girlfreind frogs help the FROGF_SEMENMAX frog if(frog1->flags&FROGF_GIRLFREIND) { if(GetBoyfriendFrog) { GetBoyfriendFrog->fly_count++; } } else frog1->fly_count++; frog1->flies_since_last_shit++; fly2=fly1->next; FrogCloseMouth(frog1,fly1->body); ServerThingDel(fly1); fly1=fly2; goto next_frog_tongue; break;case FLYT_WASP: if(fly1(CWasp*)->is_angry) { fly2=fly1->next; FrogDie(frog1); ServerThingDel(fly1); fly1=fly2; FrogCloseMouth(frog1); goto next_frog_tongue; } else { fly1(CWasp*)->is_angry=TRUE; fly1->pattern=FLY_PATTERN_ATTACK; fly1->start_ts=Server_tS(game.server); fly1->spawn_x=fly1->body->x; fly1->spawn_y=fly1->body->y; fly1->btarget_x=ClampI64(frog1->body->x+RandI64%100,0,GR_WIDTH); fly1->btarget_y=ClampI64(frog1->body->y-200+RandI64%50,10,GR_HEIGHT/2); FrogCloseMouth(frog1); goto next_frog_tongue; } } } else fly1=fly1->next; } else fly1=fly1->next; next_fly: } } next_frog_tongue: if(frog1->y>=GROUND_POSITION) { frog1->hit_vector=0; } } for(frog1=game.frogs.next;frog1!=&game.frogs;frog1=frog1->next) { for(frog2=game.frogs.next;frog2!=&game.frogs;frog2=frog2->next) { if(frog1!=frog2) { if(frog1->flags&FROGF_MOUTH_OPEN&&!(frog1->flags&FROGF_DEAD)) { if(C2DObjectCollisionTest(frog1->tongue,frog2->body)) { tongue_hit: FrogCloseMouth(frog1); goto next_frog_tongue2; } else if(C2DObjectCollisionTest(frog1->tongue,frog2->head)) { goto tongue_hit; } else if(C2DObjectCollisionTest(frog1->tongue,frog2->tongue)) { goto tongue_hit; } } } next_frog_tongue2:; if(frog1!=frog2&&!(frog1->flags&FROGF_DEAD)) { if(C2DObjectCollisionTest(frog1->body,frog2->body)) { body_hit: if(!(frog1->flags&FROGF_SITTING)) if(!Bts(&frog1->hit_bitmap,frog2->id)) { if(frog1->y>=frog2->y) { FrogBeginJump(frog1,frog1->looking_at_x,frog1->y+100,200,TRUE); if(frog1->x>=frog2->x) FrogBeginJump(frog2,frog2->x-100,frog2->y-100,100,TRUE); else FrogBeginJump(frog2,frog2->x+100,frog2->y-100,100,TRUE); break; } } } else if(C2DObjectCollisionTest(frog1->body,frog2->head)) { goto body_hit; } else if(C2DObjectCollisionTest(frog1->body,frog2->tongue)) { goto body_hit; } } } } Refresh; } Kill(level); Kill(game.day_task); SettingsPop; C2DWorldDel(game.world); } U0 AssBlastFinish(CFrog *f) { CTurd *t,*tn; if(QueCnt(&f->ass_blast.turds)) { for(t=f->ass_blast.turds.next;t!=&f->ass_blast.turds;t=tn) { tn=t->next; TurdProjectileDel(t); } } QueInit(&f->ass_blast.turds); } U0 InitAssBlastForFrog(CFrog *f,I64 turds,Bool propel_into_air=TRUE) { CTurd *t,*tn; if(!turds) return; if(!f->ass_blast.turds.next) QueInit(&f->ass_blast.turds); f->flies_since_last_shit=0; f->ass_blast.freq=15; f->ass_blast.duration=ToF64(turds)/10; f->ass_blast.start_ts=Server_tS(game.server); f->ass_blast.next_turd_ts=Server_tS(game.server); f->ass_blast.propel_into_air=propel_into_air; f->flags|=FROGF_SHITTING; } U0 ContinueAssBlast(CFrog *f) { CTurd *turd,*tn; for(turd=f->ass_blast.turds.next;turd!=&f->ass_blast.turds;turd=tn) { tn=turd->next; if(turd->state==TURDS_DONE) { TurdProjectileDel(turd); } else TurdProjectileMove(turd); } if(!(f->flags&FROGF_SHITTING)) return; F64 t=Server_tS(game.server)-f->ass_blast.start_ts,x,y,vx,vy,angle; if(t>f->ass_blast.duration) { f->flags&=~FROGF_SHITTING; } else if(Server_tS(game.server)>f->ass_blast.next_turd_ts) { f->ass_blast.next_turd_ts=Server_tS(game.server)+1./f->ass_blast.freq; turd=CAlloc(sizeof CTurd); turd->start_ts=Server_tS(game.server); turd->state=TURDS_PROJECTILE; turd->turdg=C2DObjectNewFromSprite($IB,"<12>",BI=12$,game.game_task); turd->turdg->priority=TURD_DRAW_PRIORITY+f->id*FROG_DRAW_PRIORITY+QueCnt(&f->ass_blast.turds); f->flags|=FROGF_SHITTING; if(f->ass_blast.propel_into_air) { //Shitting will propel the fucking frog into the air f->y-=turd->turdg->height; x=f->looking_at_x-f->x; y=f->looking_at_y-f->y; angle=Arg(x,y); vy=-FROG_SHIT_VELOCITY*Sin(angle); vx=FROG_SHIT_VELOCITY*Cos(angle)*Abs(Rand); f->jump_start_x=f->x; f->jump_start_y=f->y; turd->xvelo=-vx; f->jump_start_angle=angle; f->flags&=~FROGF_SITTING; f->jump_start_ts=Server_tS(game.server); f->yvelo+=vy; f->xvelo+=vx; turd->turdg->x=f->x; turd->turdg->y=f->y; } else{ turd->turdg->x=f->x; turd->turdg->y=f->y-20; if(f->body->flipped){ vy=-FROG_SHIT_VELOCITY*Sin(pi+pi/8); vx=FROG_SHIT_VELOCITY*Cos(pi+pi/8)*Abs(Rand); turd->turdg->x+=+0xe*8; } else { vy=-FROG_SHIT_VELOCITY*Sin(pi+pi/8); vx=-FROG_SHIT_VELOCITY*Cos(pi+pi/8)*Abs(Rand); } turd->xvelo=-vx; } C2DObjectUpdateMat(turd->turdg); AddObjectToWorld(turd->turdg,game.world); QueIns(turd,f->ass_blast.turds.last); if(game.sound_task&&!TaskValidate(game.shit_sound_task)) { Kill(game.sound_task); game.sound_task=ShitSound2(1000./f->ass_blast.freq,,,,f->ass_blast.duration/ToF64(f->ass_blast.freq)); game.shit_sound_task=game.sound_task; } } } U0 TurdProjectileMove(CTurd *p) { F64 t=tS-p->start_ts,old_x=p->turdg->x,old_y=p->turdg->y; CFrog *frog; switch(p->state) { break;case TURDS_PROJECTILE: C2DObjectSetGraphicsFromSprite(p->turdg,$IB,"<12>",BI=12$); p->turdg->x+=p->xvelo; p->turdg->y+=p->yvelo; if(p->xvelo<0) C2DObjectSetFlip(p->turdg,TRUE); p->turdg->rot=Arg(p->xvelo,p->yvelo); p->yvelo=t*TURD_GRAVITY; if(p->turdg->x<0) { p->turdg->x; goto become_splat; } if(p->turdg->x>=GR_WIDTH) { p->turdg->x=GR_WIDTH; goto become_splat; } if(p->turdg->y>=GROUND_POSITION) { p->turdg->y=GROUND_POSITION; goto become_ground; } return ; become_splat: p->state=TURDS_MELT; p->start_ts=tS; p->xvelo=0; p->yvelo=TURD_MELT_SPEED; p->melt_percent=0; return; become_ground: p->state=TURDS_GROUND; p->start_ts=tS; p->xvelo=0; p->yvelo=0; p->melt_percent=0; return; break;case TURDS_MELT: p->turdg->rot=0; p->turdg->x+=p->xvelo; p->turdg->y+=p->yvelo; C2DObjectSetGraphicsFromSprite(p->turdg,$IB,"<13>",BI=13$); if(p->turdg->xturdg,TRUE); } if(p->turdg->y>=GROUND_POSITION) { p->turdg->y=GROUND_POSITION; goto become_ground; } break;case TURDS_GROUND: case TURDS_STEPPED_ON: C2DObjectSetGraphicsFromSprite(p->turdg,$IB,"<14>",BI=14$); p->turdg->rot=0; if(t>=0.75) { free: p->state=TURDS_DONE; } else { C2DObjectScale(p->turdg,1-t); } for(frog=game.frogs.next;frog!=&game.frogs;frog=frog->next) { if(C2DObjectCollisionTest(p->turdg,frog->body)) { p->state=TURDS_STEPPED_ON; frog->flags|=FROGF_SHIT_FEET; frog->shit_feet_time=tS; p->start_ts=tS; break; } } } } //"Reset" the game data(Including world graphics) U0 GameClear() { CQue *obj,*next; game.player=NULL; if(game.sound_task) Kill(game.sound_task); if(game.day_task) Kill(game.day_task); for(obj=game.server->things;obj!=&game.server->things;obj=obj->next) { ServerThingDel(obj); } for(obj=game.world->objects.next;obj!=&game.world->objects;obj=next) { next=obj->next; C2DObjectDel(obj); } game.done=FALSE; } U0 GirlfreindFrogAI(CFrog *gf) { CFrog *loves_frog; for(loves_frog=game.frogs.next;loves_frog!=&game.frogs;loves_frog=loves_frog->next) { if(loves_frog->flags&FROGF_SEMENMAX) { goto found; } } goto leave; found: if(gf->ai_state[2]==1) { leave: if(gf->x<=-200.) { gf->lives=0; gf->flags|=FROGF_DEAD; return; } gf->flags|=FROGF_LEAVE_STAGE; gf->looking_at_x=-300; gf->looking_at_y=GROUND_POSITION-100; if(!(gf->flags&FROGF_SITTING)) return; FrogBeginJump(gf,gf->looking_at_x,gf->looking_at_y,FROG_JUMP_VELOCITY/2,TRUE); return; } if(loves_frog->power_up_end_ts<=Server_tS(game.server)) { gf->ai_state[2]=1; gf->speech_text=StrNew("Im bored\ngunna find\another frog",game.game_task); gf->speech_end_ts=Server_tS(game.server)+.75; goto leave; } //Frog FrogAI0(gf); } CFrog *MakeGirlfreindFrog(CFrog *for_frog) { CFrog *cpu=AddFrog(FALSE,400); cpu->flags=FROGF_GIRLFREIND; cpu->color=LTPURPLE; StrCpy(cpu->ai,"GirlfreindFrogAI"); cpu->reference_head_open=C2DObjectNewFromSprite($IB,"<16>",BI=16$,game.game_task); cpu->reference_head_close=C2DObjectNewFromSprite($IB,"<17>",BI=17$,game.game_task); cpu->lives=1; } //Game(&GameLevel0,GAMEF_DAY_CYCLE|GAMEF_CHAT_LOG); //Game(&AbortionSceneLevel); @,40ιP 5?1    KYTX: !U1 rZH= C: $wv5v<<{BBFKkHn574/>6@/H3I3NMD; 0771)C  =J @MDIE07!@&JFK;TDS;`H]  : + .[BG FJ=[ UJL\ [R Q [ W P# &-8EOGZ6O**+ - T<*<%3))))6; ? KfVOC .!' >JE=;10&%-H2] 4&@0@/@2 2= KW ("; ? KhiZC .' >JE=;10&%-H2]4&@0@/@2 2= KZ ( - CaG;2V:","  !!,.:   .A   )? *!0& 0F *= ("F<   :   !5  &@ "'! *D .3 ("9E   2 [;     Z:     A >)J.:6*6!  !  '  (   &FV ZN=(  E ] E! & "    : P >    3 X?4 oO"? t%6 - %    0  ?7G Q @# ) "! > c X E 5 /  I 3 R{W& R#GEP RS|/v>$ (@&$@8,73:8BHH7<QOJWWabeZZ<^:aX'YcWS H ?C=!B<DFCH;53 61 ;<%,^-3#T@ F6$j5IQƶ ۶[-E 5&  0$'3-0.#(  &#%, .# %#0 3  +* I Love Niggers   `!' a!~l/n<: 0ED)$3NP$'`&]7" ~ @ b5 g7g7D9s6 7}6$A?I u IڿI?IDamm6`ID$I$ymݶm۶ #" 8;7:# Semen Max(  2> 1  .K)LR@>0XI 74 (   #1 G @& *1 *   6<) )JOI[9N#9%2 V>6<03' L- @-% 5- /#%GR_WIDTH; fly->btarget_y=RandU64%(GROUND_POSITION-75); fly->end_x=RandU64%GR_WIDTH; fly->end_y=Rand%(GROUND_POSITION-75); break; } return fly; } CWasp *WaspNew(F64 x,F64 y) { CWasp *wasp=ConstructThing(#ifndef LOBBY_H #define LOBBY_H #include "../UI.HC" #include "../Server.HC" CQue ui_root; class CPlayer:CServerThing { I64 color dft LTGREEN; U8 name[STR_LEN-2],ready,started_game; U64 token; }; class CStartGame { U8 host[STR_LEN]; U8 path[STR_LEN]; I64 port,token; }; Bool lobby_ended=0; #define LOBBY_WIDTH (GR_WIDTH-100) #define LOBBY_HEIGHT (GR_HEIGHT-100) class CLobby:CServerThing { CUIChatLog *chat_log; CUITextBar *chat_log_typer; CUILabel *title; CUIButton *ready; CUIScrollBars *players; CUILabel *status_label; CServer *server; F64 untill_start; F64 start_ts; I64 min_players; CPlayer *client_player; Bool done,countdown_started,pad[6]; U8 title_text[STR_LEN]; CStartGame *_start_game; CStartGame *(*start_game_cb)(); } *lobby; class CLobbyNameChange { I64 player_id; U8 name[STR_LEN]; }; class CLobbyColorChange { I64 player_id; I64 color; }; class CLobbyChatMessage { I64 player_id; U8 message[STR_LEN]; }; class CLobbyWhoAmI { I64 i_am_id; }; U0 Lobby_ServerGetChatMsg(CServer *s,CMessagePass *pass) { CLobbyChatMessage *msg=pass->body; CPlayer *p=ServerId2Ptr(s,msg->player_id); if(p&&ThingHasClass("CPlayer",p)) { ServerPassMessageToAllClients(s,"Lobby_ClientGetChatMsg",msg,sizeof(CLobbyChatMessage)); } } U0 ServerBroadcastMessage(CServer *s,U8 *msg) { CLobbyChatMessage cmsg; cmsg.player_id=-1; StrCpy(cmsg.message,msg); ServerPassMessageToAllClients(s,"Lobby_ClientGetChatMsg",&cmsg,sizeof(CLobbyChatMessage)); } U0 Lobby_ClientGetChatMsg(CServer *s,CMessagePass *pass) { CLobbyChatMessage *msg=pass->body; CPlayer *p=ServerId2Ptr(s,msg->player_id); U8 *str; if(p&&ThingHasClass("CPlayer",p)) { str=MStrPrint("%s:",p->name); UIChatLogAddLine(lobby->chat_log,str,msg->message,p->color); Free(str); } else { UIChatLogAddLine(lobby->chat_log,"???:",msg->message,LTGRAY); } } U0 Lobby_PlayerJoin(CServer *s,CMessagePass *pass) { CPlayer *p=ConstructServerThing(s->mem_task,"CPlayer"); U8 *name=MStrPrint("%s%s",god.words[RandU64%god.num_words], god.words[RandU64%god.num_words]),*str2; StrCpy(p->name,name); p->token=HashStr(name); Free(name); AddThingToServer(p,s); name=UDPAddrToStr(CurrentClient->to); str2=MStrPrint("PLAYER_ID:%s",name); FramePtrAdd(str2,p->id,s->mem_task); Free(str2),Free(name); } CPlayer *CurrentClientPlayer(CServer *s) { if(s->mode==SERV_MODE_CLIENT) return lobby->client_player; CPlayer *p=NULL; U8 *name=UDPAddrToStr(CurrentClient->to),*str2; str2=MStrPrint("PLAYER_ID:%s",name); if(FramePtr(str2,s->mem_task)) { p=ServerId2Ptr(s,FramePtr(str2,s->mem_task)); if(p&&!ThingHasClass("CPlayer",p)) p=NULL; } Free(name),Free(str2); return p; } U0 Lobby_ServerGetColorChange(CServer *s,CMessagePass *pass) { CLobbyColorChange *cc=pass->body; CPlayer *p=CurrentClientPlayer(s); U8 *str=NULL; if(p) { if(p->color!=cc->color) ServerBroadcastMessage(s,str=MStrPrint("'%s' changed color to something juicy.",p->name)); Free(str); p->color=cc->color; } } U0 Lobby_ServerGetNameChange(CServer *s,CMessagePass *pass) { CLobbyNameChange *cn=pass->body; CPlayer *p=CurrentClientPlayer(s); U8 *str=NULL; if(p) { if(StrCmp(p->name,cn->name)) ServerBroadcastMessage(s,str=MStrPrint("'%s' became '%s'.",p->name,cn->name)); Free(str); StrCpy(p->name,cn->name); } } U0 Lobby_ServerGetPlayerWhoAmI(CServer *s,CMessagePass *pass) { CLobbyWhoAmI msg; if(CurrentClientPlayer(s)) { msg.i_am_id=CurrentClientPlayer(s)->id; ServerPassMessageToClient(s,"Lobby_ClientGetPlayerWhoAmI",&msg,sizeof(CLobbyWhoAmI)); } } U0 Lobby_ClientGetPlayerWhoAmI(CServer *s,CMessagePass *pass) { CLobbyWhoAmI *me=pass->body; CPlayer *p=ServerId2Ptr(s,me->i_am_id); if(p&&ThingHasClass("CPlayer",p)) { lobby->client_player=p; } } //Called when Client gets Lobby_ClientStartGame U0 Lobby_ServerClientDone(CServer *s,CMessagePass *pass) { CPlayer *p=CurrentClientPlayer(s); if(p) { p->started_game=TRUE; ServerThingDel(s,p); } } U0 Lobby_ClientStartGame(CServer *s,CMessagePass *pass) { CStartGame *sg=pass->body; CPlayer *p=lobby->client_player; if(p) { ServerThingDel(s,p); ClientPassMessageImportant(s,"Lobby_ServerClientDone","",0); DefinePrint("CLIENT",""); DefinePrint("GAME_HOST","\"%Q\"",sg->host); DefinePrint("GAME_PORT","%d",sg->port); DefinePrint("GAME_TOKEN","%d",sg->token); DefinePrint("PLAYER_NAME","\"%Q\"",p->name); lobby_ended=TRUE; lobby->client_player=NULL; } } U0 TextBarEnter(CUIElem *,U8 *text) { CLobbyChatMessage msg; CPlayer *p=CurrentClientPlayer(lobby->server); if(p) { msg.player_id=p->id; StrCpy(msg.message,text); ClientPassMessage(lobby->server,"Lobby_ServerGetChatMsg",&msg,sizeof(CLobbyChatMessage)); } } $SP,"<1>",BI=1$ I64 ReadyCallback(CUIButton *b,I64,I64) { if(lobby->client_player) { lobby->client_player->ready^=TRUE; ClientPassMessageImportant(lobby->server,"Lobby_SetPlayerReady",&lobby->client_player->ready,1); if(lobby->client_player->ready) b->label=StrNew("Ready!",ui_task); else b->label=StrNew("Not Ready",ui_task); } } U0 Lobby_SetPlayerReady(CServer *s,CMessagePass *pass) { CPlayer *p=CurrentClientPlayer(s); if(p) p->ready=pass->body(U8*)[0]; } U0 LobbyDel() { CUIElem *e,*head=&ui_root,*next; for(e=head->next;e!=head;e=next) { next=e->next; UIKillElem(e); } QueInit(&ui_root); //Remove from server things QueRem(lobby); ServerDel(lobby->server); Free(lobby); } U0 LobbyInitData() { CUIElem *elem,*elem2,*main_body; QueInit(&ui_root); main_body=UIBackgroundNew(LOBBY_WIDTH,LOBBY_HEIGHT,LTGRAY); QueIns(main_body,&ui_root); elem=UICenterNew(main_body,TRUE,FALSE); elem2=UILabelNew(lobby->title_text,YELLOW); QueIns(elem2,elem->sub_elems.last); QueIns(elem,main_body->sub_elems.last); lobby->title=elem2; lobby->players=UIScrollBarsNew((LOBBY_WIDTH-3*16)*1/2.,LOBBY_HEIGHT-8-2*16,LTBLUE); QueIns(lobby->players,&main_body->sub_elems); lobby->players->x=16; lobby->players->y=16+8; lobby->chat_log=UIChatLogNew((LOBBY_WIDTH-3*16)*1/2./8,(LOBBY_HEIGHT-8-3*16)/8); QueIns(lobby->chat_log,&main_body->sub_elems); lobby->chat_log_typer=UITextBarNew("",(LOBBY_WIDTH-3*16)*1/2.); QueIns(lobby->chat_log_typer,&main_body->sub_elems); lobby->chat_log_typer->enter_cb=&TextBarEnter; lobby->chat_log->x=(LOBBY_WIDTH-3*16)*1/2.+16*2; lobby->chat_log_typer->x=(LOBBY_WIDTH-3*16)*1/2.+16*2; lobby->chat_log_typer->y=LOBBY_HEIGHT-8-2*16+8; lobby->chat_log->y=16+8; lobby->chat_log->bg_color=LTRED; lobby->chat_log->fg_color=BLUE; lobby->status_label=UILabelNew(""); QueIns(lobby->status_label,&main_body->sub_elems); lobby->ready=UIButtonNew("Start Game",12*8,12); lobby->ready->y=LOBBY_HEIGHT-8-6; lobby->ready->x=LOBBY_WIDTH-12*8-16; lobby->ready->fg_color=BLACK; lobby->ready->bg_color=GREEN; lobby->ready->ms_ldown=&ReadyCallback; QueIns(lobby->ready,&main_body->sub_elems); } U0 LobbyNew(U8 *title,F64 till_start=-1,I64 min_players=1) { lobby=ConstructServerThing(ui_task,"CLobby"); if(till_start<0) till_start=10; lobby->untill_start=till_start; lobby->min_players=min_players; StrCpy(lobby->title_text,title); LobbyInitData; } U0 LobbyClientNew(U8 *host="127.0.0.1",I64 port=8001) { CServer *server=ClientNew(host,port); CLobby *c,*head=&server->things; while(!lobby) { ClientAskForUpdates(server); for(c=head->next;c!=head;c=c->next) { if(ThingHasClass("CLobby",c)) { lobby=c; break; } } Yield; } LobbyInitData; lobby->server=server; } I64 PlayerSort(CPlayer *a,CPlayer *b) { return a->id-b->id; } I64 ChangeColorButtonCb(CUIButton *,I64,I64) { CPlayer *p=CurrentClientPlayer(lobby->server); CLobbyColorChange change; if(p) { change.player_id=p->id; change.color=PopUpColor("Choose Color:"); ClientPassMessageImportant(lobby->server,"Lobby_ServerGetColorChange",&change,sizeof(CLobbyColorChange)); } } I64 LobbyStatusLabelUpdate() { I64 cnt=0; U8 *str; CPlayer *p,*head=&lobby->server->things; for(p=head->next;p!=head;p=p->next) if(ThingHasClass("CPlayer",p)) cnt++; if(lobby->countdown_started) { str=MStrPrint("Countdown:%f more seconds.", lobby->start_ts-Server_tS(lobby->server)); } else { if(lobby->min_playersmin_players); } else { str=MStrPrint("Have %d Players.",cnt); } } Free(lobby->status_label->label); lobby->status_label->color=YELLOW; lobby->status_label->label=StrNew(str,ui_task); lobby->status_label->x=16; lobby->status_label->y=LOBBY_HEIGHT-8-4; Free(str); } I64 ChangeNameButtonCb(CUIButton *,I64,I64) { CPlayer *p=CurrentClientPlayer(lobby->server); CLobbyNameChange change; U8 *str; if(p) { change.player_id=p->id; str=PopUpGetStr("New Name:"); if(str) StrCpy(change.name,str); else StrCpy(change.name,""); ClientPassMessageImportant(lobby->server,"Lobby_ServerGetNameChange",&change,sizeof(CLobbyNameChange)); Free(str); } return 1; } U0 UpdatePlayersWindow() { I64 cnt=0,idx; CPlayer **players; CServerThing *p,*head=&lobby->server->things; CUIElem *e,*next; for(p=head->next;p!=head;p=p->next) { if(ThingHasClass("CPlayer",p)) { cnt++; } } players=MAlloc(8*cnt); cnt=0; for(p=head->next;p!=head;p=p->next) { if(ThingHasClass("CPlayer",p)) { players[cnt++]=p; } } QSortI64(players,cnt,&PlayerSort); head=&lobby->players->sub_elems; for(e=head->next;e!=head;e=next) { next=e->next; UIKillElem(e); } for(idx=0;idx!=cnt;idx++) { if(lobby->client_player==players[idx]) { e=UILabelNew(players[idx]->name,players[idx]->color); e->y=10*idx; QueIns(e,head->last); e->y=10*idx; e=UIButtonNew("Name",4*8,8); e->y=10*idx; e->user_data=players[idx]->id; e->x=8*StrLen(players[idx]->name)+8; e->ms_ldown=&ChangeNameButtonCb; QueIns(e,head->last); e=UIButtonNew("Color",5*8,8); e->ms_ldown=&ChangeColorButtonCb; e->y=10*idx; e->user_data=players[idx]->id; e->x=8*StrLen(players[idx]->name)+8+4*8+8; QueIns(e,head->last); } else { e=UILabelNew(players[idx]->name,players[idx]->color); e->y=10*idx; QueIns(e,head->last); } } Free(players); } U0 DrawIt(CTask *t,CDC *dc) { RenderUI(dc,&ui_root,0,0,t->pix_width,t->pix_height); } U0 LobbyServerIdle(CServer *s) { CServerThing *head=&s->things,*cur; COutgoing *og; CStartGame sg; U8 *name,*check; I64 player_cnt=0; I64 ready_cnt=0; for(cur=head->next;cur!=head;cur=cur->next) { if(ThingHasClass("CPlayer",cur)) { player_cnt++; if(cur(CPlayer*)->ready) ready_cnt++; } } if(ready_cnt==player_cnt&&player_cnt) goto done; if(player_cnt>=lobby->min_players) { if(lobby->countdown_started) { //Countdown is active if(lobby->start_ts<=Server_tS(s)) { done: if(!lobby->done&&lobby->start_game_cb) lobby->_start_game=(*lobby->start_game_cb)(); lobby->done=TRUE; } } else { lobby->countdown_started=TRUE; lobby->start_ts=Server_tS(s)+lobby->untill_start; } } else { lobby->countdown_started=FALSE; } if(lobby->done&&lobby->_start_game) { player_cnt=0; head=&s->clients; for(og=head->next;og!=head;og=og->next) { name=UDPAddrToStr(og->to); check=MStrPrint("PLAYER_ID:%s",name); cur=ServerId2Ptr(s,FramePtr(check)); Free(check); Free(name); if(cur&&ThingHasClass("CPlayer",cur)) { MemCpy(&sg,lobby->_start_game,sizeof(CStartGame)); sg.token=cur(CPlayer*)->token; ServerPassMessageToClient(s,"Lobby_ClientStartGame",&sg,sizeof(CStartGame)); player_cnt++; PrintI("p",cur->thing_flags&SRV_THINGF_TO_DELETE); } } if(!player_cnt) lobby->done=2; } } U0 LobbyServerNew(CStartGame *(*start_game_cb)(),U8 *host="127.0.0.1",I64 port=8001,U8 *title,F64 till_start=-1,I64 min_players=1) { LobbyNew(title,till_start,min_players); lobby->server=ServerNew(host,port); lobby->server->idle=&LobbyServerIdle; lobby->start_game_cb=start_game_cb; AddThingToServer(lobby,lobby->server); } U0 LobbyServerWaitForGame() { //Done is set to 2 when all clients are connected to the game while(lobby->done!=2) Sleep(1000); Sleep(60); DefinePrint("SERVER","1"); if(lobby->_start_game) { DefinePrint("GAME_HOST","\"%Q\"",lobby->_start_game->host); DefinePrint("GAME_PORT","%d",lobby->_start_game->port); } } U0 LobbyInteract() { I64 msg,arga,argb; Bool i=0; ClientPassMessageImportant(lobby->server,"Lobby_PlayerJoin","Billy Jean",0); Fs->draw_it=&DrawIt; WinMax; WinBorder; LBts(&(Fs->win_inhibit),WIf_FOCUS_TASK_MS_L_D); LBts(&(Fs->win_inhibit),WIf_FOCUS_TASK_MS_R_D); while(!lobby_ended) { while(msg=ScanMsg(&arga,&argb)) { UpdateUI(&ui_root,msg,arga,argb); } if(!lobby->client_player) { ClientPassMessage(lobby->server,"Lobby_ServerGetPlayerWhoAmI","Dirty Diana",0); } if(ClientAskForUpdates(lobby->server)) { UpdatePlayersWindow; LobbyStatusLabelUpdate; } Refresh; } Fs->draw_it=NULL; } /*#ifdef CLIENT LobbyClientNew; LobbyInteract; LobbyDel; #else CStartGame *sg() { } LobbyServerNew(NULL,,,"Demo Lobby"); User("#define CLIENT 1;\n#include \"lobby.HC\";;\n"); LobbyServerWaitForGame; LobbyDel; #endif*/ #endif  #  'title chat logChat log typer :Players#exe {Cd(__DIR__);;};; #define CLIENT #include "overworld";#exe{Cd(__DIR__);};; #include "../_3D.HC"; #exe{Cd(__DIR__);};; #include "../UI.HC"; CDC *ScaleDC(CDC *dc,I64 sz_x,I64 sz_y,CTask *mem_task=NULL) { CDC *new=DCNew(sz_x,sz_y,mem_task); I64 x,y; for(x=0;x!=sz_x;x++) for(y=0;y!=sz_y;y++) { new->color=GrPeek0(dc, Lerp(x/ToF64(sz_x),0,dc->width), Lerp(y/ToF64(sz_y),0,dc->height) ); GrPlot0(new,x,y); } return new; } CDC *ScaleAnimDC(CDC *dc,I64 sz_x,I64 sz_y,CTask *mem_task) { I64 cnt=AnimDCCnt(dc); CDC *ret=CAlloc(sizeof(CDC)*(cnt+1),mem_task); CDC *tmp; while(--cnt>=0) { tmp=ScaleDC(dc+cnt,sz_x,sz_y); MemCpy(ret+cnt,tmp,sizeof(CDC)); Free(tmp); } return ret; } CDC *Sprite2DCTransparent(U8 *sp,CTask *mem_task=NULL,I64 *xoff=NULL, I64 *yoff=NULL) { I64 min_x,max_x,min_y,max_y; CDC *dc; SpriteExtents(sp,&min_x,&max_x,&min_y,&max_y); dc=DCNew(max_x-min_x+1,max_y-min_y+1,mem_task); DCFill(dc,TRANSPARENT); Sprite3(dc,-min_x,-min_y,0,sp); if(xoff) *xoff=min_x; if(yoff) *yoff=min_x; return dc; } /* $BK,1$ ,---. | o ,---. |---'. .,---.|---..,---. |---' | | |`---.| ||| | | ` `---'`---'` '`` ' ` $BK,0$ */ // // Server message headers // class CMsgMove { I64 who; F64 angle; //Client doesnt set velocity,server does and sends back F64 velocity; }; class CMsgUseItem { I64 user; I64 use_item; I64 target; }; class CMsgLookAt { I64 who; F64 angle; }; //CMsgUseItem extern U0 MsgToS_UseItem(CServer *s,CMessagePass *pass); //CMsgStartMove extern U0 MsgToS_StartMove(CServer *s,CMessagePass *pass); extern U0 MsgToC_StartMove(CServer *s,CMessagePass *pass); extern U0 MsgToS_EndMove(CServer *s,CMessagePass *pass); extern U0 MsgToC_EndMove(CServer *s,CMessagePass *pass); //CMsgLookAt; extern U0 MsgToS_LookAt(CServer *s,CMessagePass *pass); #define MOBILEF_COLLISION 1 #define MOBILEF_KILLABLE 2 //These do will all picking up a chest of items #define MOBILEF_PICK_UP 4 #define MOBILE_SIGNATURE 'MobileS' class CMobileTemplate:CServerThing { U8 normal_template[32]; U8 dead_template[32]; U8 attack_template[32]; U8 damage[32]; U8 collide[32]; U8 remove[32]; U8 next_state[32]; }; class CMobile:CServerThing { I64 signature; //CInventoryItem,is a linked list with CInventoryItem->next U8 *inventory_items swizzle; //Thing may be NULL for a invisible object U64 type; C2DThing *thing; U8 active_template[32]; F64 x,y,angle; F64 walk_velocity; F64 health,cur_velocity; //When 2 mobiles collison,one will push the other one F64 collision_weight; I64 flags; CMobileTemplate *tmplate swizzle; }; class COverWorld { CQue ui_root; CTask *snd_task; //These get stored off screen when not in use CUIGrid *inventory; CUIButton *inventory_button; CUIButton *exit_inventory_button; CUIGrid *quick_inventory; CUIMeter *health_meter; C3DWorld *world; I64 ms_x,ms_y; CMobile *player; CTask *mem_task; Bool left_down,right_down; } overworld; CMobileTemplate *GetTemplate( U8 *name, U8 *normal_template="", U8 *dead_template="", U8 *attack_template="", U8 *damage_cb="", U8 *collide_cb="", U8 *remove_cb="", U8 *next_state="" ) { U8 *fmt=MStrPrint("MOB_TEMPLATE:%s",name); CMobileTemplate *ret=FramePtr(fmt); if(ret) { Free(fmt); return ret; } ret=ConstructServerThing(overworld.mem_task,"CMobileTemplate"); AddThingToServer(ret,overworld.world->server); FramePtrAdd(fmt,ret); StrCpy(ret->normal_template,normal_template); StrCpy(ret->dead_template,dead_template); StrCpy(ret->attack_template,attack_template); StrCpy(ret->damage,damage_cb); StrCpy(ret->collide,collide_cb); StrCpy(ret->remove,remove_cb); StrCpy(ret->next_state,next_state); Free(fmt); return ret; } Bool MobileValidate(CMobile *m) { if(!m) return FALSE; return m->signature==MOBILE_SIGNATURE; } CMobile *MobileCollision(CMobile *self,F64 x,F64 y,F64 angle,F64 *dist=NULL,I64 inst=0) { CMobile *found=NULL; F64 tmp; CMobile *mob,*head=&overworld.world->server->things; for(mob=head->next;mob!=head;mob=mob->next) { if(self==mob) goto next; if(!ThingHasClass("CMobile",mob)) goto next; if(!MobileValidate(mob)) goto next; if(!(mob->flags&MOBILEF_COLLISION)) goto next; tmp=Sqrt(Sqr(mob->x-x)+Sqr(mob->y-y)); if(tmp<=THING_RADIUS) { if(dist) *dist=tmp; if(--inst<=0) return mob; } next:; } return NULL; } //Returns hit mobile,or NULL if hit a wall or nothing Bool MobileMove(CMobile *mob,F64 distance,Bool walk_along_wall=FALSE,CMobile **_hit_mob=NULL) { if(!MobileValidate(mob)) return FALSE; C3DWorld *w=overworld.world; F64 old_x=w->x,old_y=w->y; F64 angle=mob->angle; F64 mob_dist; F64 wall_dist=Abs(distance)*2.; F64 deflect_angle; F64 friction,old_angle; I64 side,cnt=0; Bool ret=FALSE; CMobile *hit_mob=NULL; w->x=mob->x,w->y=mob->y; if(distance<0) { distance*=-1.; angle+=pi; } while(hit_mob=MobileCollision(mob,mob->x,mob->y,angle,&mob_dist,cnt++)) { if(StrLen(mob->tmplate->collide)) CallExtStr(mob->tmplate->collide,mob,hit_mob); if(MobileValidate(hit_mob)&&StrLen(hit_mob->tmplate->collide)) { CallExtStr(hit_mob->tmplate->collide,hit_mob,mob); } } FindRayWall(w,angle,NULL,&wall_dist,&side); if(MobileValidate(hit_mob)&&hit_mob&&wall_dist>mob_dist) { if(mob_dist>distance) goto normal; if(walk_along_wall&&mob->collision_weight>hit_mob->collision_weight) { //Move lighter object friction=hit_mob->collision_weight/mob->collision_weight; old_angle=hit_mob->angle; hit_mob->angle=angle; MobileMove(hit_mob,(distance-mob_dist)*friction); hit_mob->angle=old_angle; //Move heavier object distance=mob_dist+(distance-mob_dist)*friction; ret=TRUE; } } else if(wall_distx,&mob->y,FALSE); ret=TRUE; if(walk_along_wall) { switch(side) { start: case 0: //Left deflect_angle=pi; break; case 1: //Right deflect_angle=0; break; end: MobileMove(mob,distance*Cos(deflect_angle),,_hit_mob); break; start: case 2://Top deflect_angle=2*pi-pi/2; break; case 3://Bottom deflect_angle=pi/2; break; end: MobileMove(mob,distance*Sin(deflect_angle),,_hit_mob); break; } } else { distance=wall_dist; } } else { normal: mob->x+=distance*Cos(angle); mob->y+=distance*Sin(angle); } //Thing radius is actually a square //If we are close to any wall,be sure to move back I64 wx=mob->x/GRID_SZ,wy=mob->y/GRID_SZ; if(WallForCord(w,(mob->x-THING_RADIUS)/GRID_SZ,wy)) { mob->x=wx*GRID_SZ+THING_RADIUS; ret=TRUE; } else if(WallForCord(w,(mob->x+THING_RADIUS)/GRID_SZ,wy)) { mob->x=wx*GRID_SZ+THING_RADIUS; ret=TRUE; } if(WallForCord(w,wx,(mob->y-THING_RADIUS)/GRID_SZ)) { mob->y=wy*GRID_SZ+THING_RADIUS; ret=TRUE; } else if(WallForCord(w,wx,(mob->y+THING_RADIUS)/GRID_SZ)) { mob->y=wy*GRID_SZ+THING_RADIUS; ret=TRUE; } w->x=old_x,w->y=old_y; if(_hit_mob) *_hit_mob=hit_mob; return ret; } U0 UpdateMobileGr(CMobile *mob) { if(!MobileValidate(mob)) return; if(!mob->thing) return; mob->thing->template=Get2DTemplateByName(overworld.world,mob->active_template); mob->thing->x=mob->x; mob->thing->y=mob->y; mob->thing->angle=mob->angle; } // // Items section // #define ITEMF_FREE 1 #define ITEM_SIGNATURE 'ItemS' class CInventoryItem:CServerThing { U8 *destroy dft "InventoryItemDel"; CInventoryItem *next_item swizzle; CMobile *belongs_to swizzle; I64 signature; CUIGridItem *grid_item; I64 flags; I64 cnt; F64 attack_time; F64 delay; U8 *name; CDC *icon_dc; CDC *hand_dc; CDC *hand_attack_dc; I64 hand_dc_xoff,hand_dc_yoff; I64 hand_attack_dc_xoff,hand_attack_dc_yoff; // U0 (*use_cb)(CInventoryItem *,F64 target_angle,CMobile *user); U8 use_cb[32]; //Private F64 attack_start_ts; }; //mob can be another inventory item U0 MobileAddInventoryItem(CInventoryItem *item,CMobile *mob) { CServerThing *next=NULL; if(ThingHasClass("CMobile",mob)) { next=mob->inventory_items; item->next_item=next; mob->inventory_items=item; item->belongs_to=mob; } else if(ThingHasClass("CInventoryItem",mob)) { next=mob(CInventoryItem*)->next_item; item->next_item=next; mob(CInventoryItem*)->next_item=item; item->belongs_to=mob(CInventoryItem*)->belongs_to; } } I64 InventoryItemCnt(CMobile *mob) { I64 cnt=0; CInventoryItem *item=mob->inventory_items; while(item) { item=item->next_item; cnt++; } return cnt; } U0 MobileRemoveDft(CMobile *m) { //See InventoryItemDel while(m->inventory_items) ServerThingDel(overworld.world->server,m->inventory_items); ServerThingDel(overworld.world->server,m->thing); m->signature=0; } Bool InventoryItemValidate(CInventoryItem *i) { if(!i) return FALSE; return i->signature==ITEM_SIGNATURE; } U0 InventoryItemDetachFromOwner(CInventoryItem *e) { CInventoryItem **hole,*cur; if(e->belongs_to) { hole=&e->belongs_to(CMobile*)->inventory_items; cur=e->belongs_to(CMobile*)->inventory_items; while(cur&&cur!=e) { hole=&cur->next_item; cur=cur->next_item; } *hole=e->next_item; } } U0 InventoryItemDel(CInventoryItem *e) { e->signature=0; if(e->grid_item) UIKillElem(e->grid_item); InventoryItemDetachFromOwner(e); } Bool AddItemToMobile(CMobile *mob,CInventoryItem *item) { if(!MobileValidate(mob)) return FALSE; if(!InventoryItemValidate(item)) return FALSE; CInventoryItem *item2; for(item2=mob->inventory_items;item2;item2=item2->next_item) { if(InventoryItemValidate(item2)) if(!StrCmp(item2->name,item->name)) { item2->cnt+=item->cnt; ServerThingDel(overworld.world->server,item); return TRUE; } } if(overworld.player!=mob) { if(MobileValidate(mob)) MobileAddInventoryItem(item,mob); return TRUE; } else if(MobileValidate(overworld.player)){ MobileAddInventoryItem(item,mob); return TRUE; } } class CFist:CInventoryItem { U8 *constructor dft "FistNew"; }; //Fist spirte; $SP,"<1>",BI=1$ //Fist attack sprite $SP,"<2>",BI=2$ $SP,"<3>",BI=3$ CMobile *GetClickedMobile(I64 inst=1) { CMobile *head=&overworld.world->server->things,*mob; for(mob=head->next;mob!=head;mob=mob->next) { if(ThingHasClass("CMobile",mob)) if(MobileValidate(mob)) if(mob->thing) if(IsClickOn2DThing(overworld.world,mob->thing,overworld.ms_x,overworld.ms_y)) if(--inst==0) return mob; } return NULL; } U0 FistUse(CFist *fist,F64 target_angle,CMobile *user) { CMobile *mob; if(overworld.snd_task) Kill(overworld.snd_task); overworld.snd_task=Noise(1000*.5,100,120); if(mob=GetClickedMobile&&StrLen(mob->tmplate->remove)) CallExtStr(mob->tmplate->remove,mob); } U0 FistNew(CFist *fist) { fist->cnt=-1; fist->signature=ITEM_SIGNATURE; fist->name=StrNew("Fist",overworld.mem_task); fist->attack_time=.5; fist->delay=.25; fist->icon_dc=Sprite2DCTransparent($IB,"<3>",BI=3$,overworld.mem_task, &fist->hand_dc_xoff,&fist->hand_dc_yoff); fist->hand_dc= Sprite2DCTransparent($IB,"<1>",BI=1$,overworld.mem_task, &fist->hand_dc_xoff,&fist->hand_dc_yoff); fist->hand_attack_dc= Sprite2DCTransparent($IB,"<2>",BI=2$,overworld.mem_task, &fist->hand_attack_dc_xoff,&fist->hand_attack_dc_yoff); StrCpy(fist->use_cb,"FistUse"); AddThingToServer(fist,overworld.world->server); return fist; } //Glizzy class CGlizzy:CInventoryItem { U8 *constructor dft "GlizzyNew"; }; $SP,"<4>",BI=4$ $SP,"<5>",BI=5$ $SP,"<6>",BI=6$ U0 GlizzyUse(CGlizzy *glizzy,F64 target_angle,CMobile *user) { CMobile *mob; if(overworld.snd_task) Kill(overworld.snd_task); overworld.snd_task=Noise(1000*.35,50,70); if(mob=GetClickedMobile) { if(StrLen(mob->tmplate->damage)) CallExtStr(mob->tmplate->damage,mob,100.); } if(--glizzy->cnt<=0) { ServerThingDel(overworld.world->server,glizzy); return; } } U0 GlizzyNew(CGlizzy *glizzy) { glizzy->signature=ITEM_SIGNATURE; glizzy->cnt=18; glizzy->name=StrNew("Glizzy",overworld.mem_task); glizzy->attack_time=.35; glizzy->delay=.25; glizzy->icon_dc=Sprite2DCTransparent($IB,"<6>",BI=6$,overworld.mem_task, &glizzy->hand_dc_xoff,&glizzy->hand_dc_yoff); glizzy->hand_dc= Sprite2DCTransparent($IB,"<4>",BI=4$,overworld.mem_task, &glizzy->hand_dc_xoff,&glizzy->hand_dc_yoff); glizzy->hand_attack_dc= Sprite2DCTransparent($IB,"<5>",BI=5$,overworld.mem_task, &glizzy->hand_attack_dc_xoff,&glizzy->hand_attack_dc_yoff); StrCpy(glizzy->use_cb,"GlizzyUse"); AddThingToServer(glizzy,overworld.world->server); return glizzy; } // // Player section // #define PLAYER_STATE_WALK_AROUND 1 #define PLAYER_STATE_INVENTORY 2 class CPlayer:CMobile { I64 state; F64 attack_start_ts; U8 *constructor dft "PlayerNew"; }; U0 ConstructQuickInventory() { CPlayer *p=overworld.player; if(!p) return; CInventoryItem*item; CUIGridItem *head=&overworld.quick_inventory->sub_elems,*e; for(item=p->inventory_items;item;item=item->next_item) { if(overworld.quick_inventory){ for(e=head->next;e!=head;e=e->next) if(e->user_data==item) goto next; e=UIGridItemNew(item->icon_dc,item->name,overworld.quick_inventory); if(!e) return; item->grid_item=e; e->user_data=item; } next:; } } U0 PlayerRemove(CPlayer *dude) { ServerThingDel(overworld.world->server,dude->thing); } #define MS_TURN_RATE (1./pi*.25) #define MS_TURN_MARGIN 150 CInventoryItem *GetCurrentInventoryItem() { CUIElem *e; return NULL; if(e=overworld.quick_inventory->active) if(InventoryItemValidate(e->user_data)) return e->user_data; return NULL; } U0 PlayerUpdate(CPlayer *player) { if(!MobileValidate(player)) return; CUIElem *e; C3DWorld *w=overworld.world; CInventoryItem *active; F64 time; CMsgUseItem item_use_msg; CMsgMove move; CMsgLookAt look_at; F64 turn_direction=0; //Turning by looking around edge of screen if(player->state==PLAYER_STATE_WALK_AROUND) { if(!(GR_HEIGHT-80<=overworld.ms_y<=GR_HEIGHT)) { if(overworld.ms_xid; look_at.angle=player->angle+turn_direction; ClientPassMessage(overworld.world->server,"MsgToS_LookAt",&look_at,sizeof(CMsgLookAt)); } if(GR_WIDTH>=overworld.ms_x>GR_WIDTH-MS_TURN_MARGIN) { turn_direction=Lerp(ToF64(overworld.ms_x-(GR_WIDTH-MS_TURN_MARGIN))/MS_TURN_MARGIN,0,MS_TURN_RATE); look_at.who=player->id; look_at.angle=player->angle+turn_direction; ClientPassMessage(overworld.world->server,"MsgToS_LookAt",&look_at,sizeof(CMsgLookAt)); } move.who=player->id; move.angle=player->angle; if(overworld.left_down&&!ToI64(player->cur_velocity)) { player->cur_velocity=1; //Make it appear to the client we started moving ClientPassMessage(overworld.world->server,"MsgToS_StartMove",&move,sizeof(CMsgMove)); } else if(ToI64(player->cur_velocity)) { player->cur_velocity=0; //Make it appear to the client that we stopped moving to avoud sending message again ClientPassMessage(overworld.world->server,"MsgToS_EndMove",&move,sizeof(CMsgMove)); } } if(active=GetCurrentInventoryItem) { if(active->attack_start_ts) { time=Server_tS(overworld.world->server)-active->attack_start_ts; if(active->delay+active->attack_time>=time) { goto skip_item; } active->attack_start_ts=0; } if(overworld.right_down) if(!(GR_HEIGHT-100<=overworld.ms_y<=GR_HEIGHT)) { if(!active->attack_start_ts) { use_item: item_use_msg.use_item=active->id; item_use_msg.user=overworld.player->id; item_use_msg.target=active->id; ClientPassMessage(overworld.world->server,"MsgToS_UseItem",&item_use_msg,sizeof(CMsgUseItem)); } } } skip_item: } if(overworld.health_meter) overworld.health_meter->value=player->health; w->x=player->x; w->y=player->y; w->angle=player->angle; } U0 PlayerNew(CPlayer *player) { player->signature=MOBILE_SIGNATURE; player->type='Player'; player->state=PLAYER_STATE_WALK_AROUND; player->health=100.; player->x=overworld.world->x; player->y=overworld.world->y; player->angle=overworld.world->angle; player->flags=MOBILEF_COLLISION|MOBILEF_KILLABLE| MOBILEF_PICK_UP; player->collision_weight=100.; player->walk_velocity=GRID_SZ/4; overworld.player=player; player->tmplate=GetTemplate( "Player", "", "", "", "", //damage "", //collide "PlayerRemove", "", //next state ); AddItemToMobile(player,ConstructServerThing(overworld.mem_task,"CFist")); AddItemToMobile(player,ConstructServerThing(overworld.mem_task,"CGlizzy")); AddThingToServer(player,overworld.world->server); } CPlayer *CreatePlayer() { //TODO account for connected client CPlayer *p=ConstructServerThing(overworld.mem_task,"CPlayer"); return p; } // // Chest section // U0 ChestHit(CMobile *chest,CMobile *hit) { I64 cnt,idx; CInventoryItem *item,**items=NULL; if(chest->type!='Chest') return; if(hit->flags&MOBILEF_PICK_UP) { cnt=InventoryItemCnt(chest); items=MAlloc(cnt*8); item=chest->inventory_items; for(idx=0;idx!=cnt;idx++) { items[idx]=item; item=item->next_item; } while(--cnt>=0) { item=items[cnt]; if(!AddItemToMobile(hit,item)) { goto fail; } else if(cnt) { items[cnt-1]->next_item=NULL; } } ServerThingDel(overworld.world->server,chest->thing); ServerThingDel(overworld.world->server,chest); } fail: Free(items); } U0 MobDropInventory(CMobile *mob) { I64 cnt=InventoryItemCnt(mob); if(!cnt) return; CInventoryItem *item; CMobile *chest=ConstructServerThing(overworld.mem_task,"CMobile"); chest->signature=MOBILE_SIGNATURE; chest->tmplate=GetTemplate( "Chest", "Chest", "","", "", //damage "ChestHit", "MobileRemoveDft" ); chest->flags=MOBILEF_COLLISION; chest->type='Chest'; chest->x=mob->x; chest->y=mob->y; StrCpy(chest->active_template,"Chest"); chest->angle=mob->angle; while(--cnt>=0) { InventoryItemDetachFromOwner(item=mob->inventory_items); MobileAddInventoryItem(item,chest); } chest->thing=ConstructServerThing(overworld.mem_task,"C2DThing"); AddThingToServer(chest,overworld.world->server); AddThingToServer(chest->thing,overworld.world->server); } // // Dude section // #define DUDE_TEMPLATE_WALK "Dude" #define DUDE_TEMPLATE_DEAD "Dude.Dead" #define DUDE_TEMPLATE_ATTACK "Dude.Attack" #define DUDE_STATE_WANDER 1 #define DUDE_STATE_WAIT 2 #define DUDE_STATE_PAIN 3 #define DUDE_STATE_DEAD 4 #define DUDE_STATE_ATTACK 5 #define DUDE_WALK_SPEED (ToF64(GRID_SZ)/8) class CDudeMobile:CMobile { I64 state,next_state2; F64 state_start_tS; F64 state_end_tS; I64 last_state; }; U0 DudeDamage(CDudeMobile *dude,F64 amt) { if(!MobileValidate(dude)) return; C2DThingTemplate *t; dude->health-=amt; if(dude->health<=0.) { dude->state=DUDE_STATE_DEAD; } else { dude->state=DUDE_STATE_PAIN; dude->state_start_tS=tS; dude->state_end_tS=tS+.25; } } U0 DudeNextState(CDudeMobile *dude) { if(!MobileValidate(dude)) return; U8 *template=NULL; enter: switch(dude->state) { default: start_wander: dude->state=DUDE_STATE_WANDER; dude->state_start_tS=tS; dude->state_end_tS=.25+1.5*Rand+tS; dude->angle=2*pi*Rand; case DUDE_STATE_WANDER: template=DUDE_TEMPLATE_WALK; dude->thing->no_repeat_anim=FALSE; if(tS>=dude->state_end_tS) { init_attack: if(RandU64%3==2) { dude->state_start_tS=tS; dude->state_end_tS=tS+3*ANIM_DELAY; dude->state=DUDE_STATE_WAIT; dude->next_state2=DUDE_STATE_ATTACK; break; } goto start_wander; } if(MobileMove(dude,DUDE_WALK_SPEED,TRUE)) { MobileMove(dude,-DUDE_WALK_SPEED/2,TRUE); dude->angle+=pi*1.75; } break; case DUDE_STATE_WAIT: //TODOpain template template=DUDE_TEMPLATE_WALK; if(tS>=dude->state_end_tS) { dude->state=dude->next_state2; dude->state_start_tS=tS; dude->state_end_tS=tS+3*ANIM_DELAY; } break; case DUDE_STATE_PAIN: if(tS>=dude->state_end_tS) goto start_wander; break; case DUDE_STATE_DEAD: if(dude->last_state!=DUDE_STATE_DEAD) { dude->flags&=~MOBILEF_COLLISION; AddItemToMobile(dude,ConstructServerThing(overworld.mem_task,"CGlizzy")); MobDropInventory(dude); } template=DUDE_TEMPLATE_DEAD; dude->thing->no_repeat_anim=TRUE; break; case DUDE_STATE_ATTACK: if(tS>=dude->state_end_tS) { goto start_wander; } template=DUDE_TEMPLATE_ATTACK; dude->thing->no_repeat_anim=TRUE; } if(template&&StrCmp(template,dude->active_template)) { if(template!=dude->active_template) dude->thing->anim_start_ts=tS; StrCpy(dude->active_template,template); } dude->last_state=dude->state; } U0 DudeRemove(CDudeMobile *dude) { dude->signature=0; ServerThingDel(overworld.world->server,dude->thing); ServerThingDel(overworld.world->server,dude); } CDudeMobile *CreateDude(F64 x,F64 y,F64 angle=0) { C2DThingTemplate *template; if(!Get2DTemplateByName(overworld.world,DUDE_TEMPLATE_WALK)) return NULL; CDudeMobile *dude=ConstructServerThing(overworld.mem_task,"CDudeMobile"); dude->signature=MOBILE_SIGNATURE; dude->tmplate=GetTemplate( "Dude", DUDE_TEMPLATE_WALK, DUDE_TEMPLATE_DEAD, DUDE_TEMPLATE_ATTACK, "DudeDamage", "DudeCollide", "DudeRemove", "DudeNextState" ); dude->type='Dude'; dude->flags=MOBILEF_COLLISION|MOBILEF_KILLABLE; dude->x=x; dude->y=y; dude->angle=angle; dude->health=100; dude->collision_weight=10.; dude->state=0; dude->thing=ConstructServerThing(overworld.mem_task,"C2DThing"); AddThingToServer(dude,overworld.world->server); AddThingToServer(dude->thing,overworld.world->server); return dude; } // // UI Section // U0 InventoryButtonUp(CUIButton *button,I64,I64) { if(!MobileValidate(overworld.player)) return; overworld.player(CPlayer*)->state=PLAYER_STATE_INVENTORY; overworld.inventory->flags&=~UI_ELEMF_DONT_DRAW; overworld.inventory_button->flags|=UI_ELEMF_DONT_DRAW; } U0 InitUI() { CUIElem *e; overworld.health_meter=UIMeterNew("P Power",75,100); overworld.health_meter->fg_color=LTGREEN; overworld.health_meter->bg_color=LTGRAY; overworld.health_meter->border_color=BLACK; QueIns(overworld.health_meter,&overworld.ui_root); e=overworld.health_meter; e->x=100; e->y=GR_HEIGHT-e->sz_x/2-10; e=overworld.quick_inventory=UIGridNew(12,1); QueIns(overworld.quick_inventory,&overworld.ui_root); e->x=GR_WIDTH/2-e->sz_x/2; e->y=GR_HEIGHT-e->sz_y-10; e=overworld.inventory_button=UIButtonNew("stuff",StrLen("Stuff")*8+16,16); e->x=GR_WIDTH/2-e->sz_x/2; e->y=16; QueIns(e,&overworld.ui_root); } // // End // U0 DrawIt(CTask *t,CDC *dc) { C3DWorld *w=overworld.world; CHashTable *old_table=Fs->hash_table; F64 time; CInventoryItem *item=GetCurrentInventoryItem,*head; CDC *hand_dc; I64 dc_xoff,dc_yoff; Fs->hash_table=t->hash_table; w->to_dc=dc; DCDepthBufAlloc(dc); C3DWorldCastRays(dc,w); C2DThing *thing; head=&w->server->things; for(thing=head->next;thing!=head;thing=thing->next) if(ThingHasClass("C2DThing",thing)) { Draw2DThing(w,thing); } if(item) { hand_dc=item->hand_dc; dc_xoff=item->hand_dc_xoff; dc_yoff=item->hand_dc_yoff; if(item->attack_time) { time=tS-item->attack_start_ts; if(time<=item->attack_time) { hand_dc=item->hand_attack_dc; dc_xoff=item->hand_attack_dc_xoff; dc_yoff=item->hand_attack_dc_yoff; } } GrBlot(dc,overworld.ms_x+dc_xoff,GR_HEIGHT-hand_dc->height,hand_dc); } if(overworld.player) { item=overworld.player->inventory_items; for(;item;item=item->next_item) { if(item->grid_item) if(item->cnt>0) item->grid_item->cnt=item->cnt; } } RenderUI(dc,&overworld.ui_root,0,0,t->pix_width,t->pix_height); Fs->hash_table=old_table; } U0 ServerIdle(CServer *s) { CMobile *head=&overworld.world->server->things,*mob; static Bool init=FALSE; static F64 last_ts; F64 delta,v; if(!init) { init=TRUE; last_ts=Server_tS(s); } delta=Server_tS(s)-last_ts; last_ts=Server_tS(s); for(mob=head->next;mob!=head;mob=mob->next) { if(ThingHasClass("CMobile",mob)) { if(v=mob->cur_velocity) { MobileMove(mob,v,TRUE); } if(StrLen(mob->tmplate->next_state)) CallExtStr(mob->tmplate->next_state,mob); UpdateMobileGr(mob); } } } U0 KillServerCb() { //TODO replace ServerDel(overworld.world->server); Exit; } U0 OverWorldServer(U8 *filename) { C2DThing *head,*thing,*next_thing; overworld.mem_task=Fs; overworld.world=LoadWorldFromFile(filename,,FALSE); head=&overworld.world->server->things; overworld.world->server->idle=&ServerIdle; Fs->task_end_cb=&KillServerCb; for(thing=head->next;thing!=head;thing=next_thing) { next_thing=thing->next; if(ThingHasClass("C2DThing",thing)) { //Replace the things with CMobile counterparts if(thing->template==Get2DTemplateByName(overworld.world,"Dude")) { CreateDude(thing->x,thing->y,thing->angle); ServerThingDel(overworld.world->server,thing); } else if(thing->template==Get2DTemplateByName(overworld.world,"Spawn")) { ServerThingDel(overworld.world->server,thing); } else { //??? Unsed thing ServerThingDel(overworld.world->server,thing); } } } } U0 OverWorldClient(U8 *filename) { CMobile *mob; C2DThing *thing,*next_thing,*head; I64 msg,msg_a,msg_b; DocClear; WinMax; WinBorder; //See WinQueIPMsgs,needed to avoid waiting for dbl click Bts(&(Fs->win_inhibit),WIf_FOCUS_TASK_MS_L_D); Bts(&(Fs->win_inhibit),WIf_FOCUS_TASK_MS_R_D); MemSet(&overworld,0,sizeof(COverWorld)); QueInit(&overworld.ui_root); InitUI; overworld.mem_task=Fs; overworld.ms_x=GR_WIDTH/2; overworld.ms_y=GR_HEIGHT/2; overworld.world=LoadWorldFromFile(filename,,TRUE); ClientPassMessageImportant(overworld.world->server,"MsgToS_PlayerNew","",0); head=&overworld.world->server->things; while(TRUE) { ClientAskForUpdates(overworld.world->server); for(thing=head->next;head!=thing;thing=thing->next) { if(ThingHasClass("CPlayer",thing)) { overworld.player=thing; goto enter; } } } enter: Fs->task_end_cb=&KillServerCb; Fs->draw_it=&DrawIt; while(TRUE) { while(msg=ScanMsg(&msg_a,&msg_b)) { switch(msg) { case MSG_MS_MOVE: overworld.ms_x=msg_a; overworld.ms_y=msg_b; break; case MSG_MS_L_DOWN: overworld.left_down=TRUE; break; case MSG_MS_R_DOWN: overworld.right_down=TRUE; break; case MSG_MS_L_UP: overworld.left_down=FALSE; break; case MSG_MS_R_UP: overworld.right_down=FALSE; break; case MSG_KEY_DOWN: if(msg_a==CH_ESC) goto en; break; } UpdateUI(&overworld.ui_root,msg,msg_a,msg_b); } PlayerUpdate(overworld.player); if(ClientAskForUpdates(overworld.world->server)) { ConstructQuickInventory; for(thing=head->next;head!=thing;thing=thing->next) { if(ThingHasClass("CMobile",thing)){ UpdateMobileGr(thing); } } } Refresh(0); } en: Exit; } // // Server message sections // CPlayer *GetClientPlayer(CServer *s) { CPlayer *p; if(s->mode==SERV_MODE_CLIENT) return overworld.player; U8 *con_name=UDPAddrToStr(CurrentClient->to),*name; name=MStrPrint("PLAYER:%s",con_name); p=FramePtr(name,s->mem_task); Free(con_name),Free(name); return p; } U0 MsgToS_PlayerNew(CServer *s,CMessagePass *pass) { CPlayer *p=GetClientPlayer(s); if(p) return; p=ConstructServerThing(overworld.world->server->mem_task,"CPlayer"); U8 *con_name=UDPAddrToStr(CurrentClient->to),*name; name=MStrPrint("PLAYER:%s",con_name); p=FramePtrAdd(name,p,s->mem_task); Free(con_name),Free(name); } U0 MsgToC_StartMove(CServer *s,CMessagePass *pass) { CMsgMove *data=pass->body; CMobile *mob=ServerId2Ptr(s,data->who); if(mob&&ThingHasClass("CMobile",mob)) { mob->cur_velocity=data->velocity; mob->angle=data->angle; } } U0 MsgToS_EndMove(CServer *s,CMessagePass *pass) { //TODO what if moving non player CMsgMove *data=pass->body; CPlayer *pl=GetClientPlayer(s); if(!pl) return; pl->cur_velocity=0; } U0 MsgToC_EndMove(CServer *s,CMessagePass *pass) { //Here's the deal,StartMove has a velocity,ill set the velocity to 0 here then start moving at zero velocity dude pass->body(CMsgMove*)->velocity=0; MsgToC_StartMove(s,pass); } U0 MsgToS_StartMove(CServer *s,CMessagePass *pass) { //TODO what if moving non player CMsgMove *data=pass->body; CPlayer *pl=GetClientPlayer(s); if(!pl) return; pl->cur_velocity=pl->walk_velocity; } U0 MsgToS_UseItem(CServer *s,CMessagePass *pass) { F64 old_x=overworld.world->x,old_y=overworld.world->y,angle; F64 face,x,y,wall_dist,tar_dist; I64 cnt; CMsgUseItem *data=pass->body; CMobile *user=ServerId2Ptr(s,data->user),*target=ServerId2Ptr(s,data->target); CInventoryItem *use_item=ServerId2Ptr(s,use_item); if(!user||!target||!use_item) return; //Check for wall collision for left/right/center face=user->angle+pi/2; for(cnt=0;cnt!=3;cnt++) { switch(cnt) { case 0: //Left side x=x+target->x-Cos(face)*THING_RADIUS; y=y+target->y-Sin(face)*THING_RADIUS; break; case 1: //Center x=target->x; y=target->y; break; case 2: //Right x=x+target->x+Cos(face)*THING_RADIUS; y=y+target->y+Sin(face)*THING_RADIUS; break; } tar_dist=Sqrt(Sqr(x-user->x)+Sqr(y-user->y)); overworld.world->x=user->x; overworld.world->y=user->y; if(-1!=FindRayWall(overworld.world,angle=Arg(x-user->x,y-user->y),,&wall_dist)) { if(tar_distuse_cb,use_item,angle,user,target); break; } } overworld.world->x=old_x,overworld.world->y=old_y; if(ThingHasClass("CPlayer",user)) user(CPlayer*)->attack_start_ts=Server_tS(s); } U0 MsgToS_LookAt(CServer *s,CMessagePass *pass) { F64 angle=pass->body(CMsgLookAt*)->angle; //TODO what if angling something not player CPlayer *pl=GetClientPlayer(s); if(!pl||!ThingHasClass("CPlayer",pl)) return; pl->angle=angle; }$ER$ #ifndef CLIENT OverWorldServer("../Untitled.WORLD.Z"); CTask *c=User( "Cd(\"%Q\");;\n" "#define CLIENT\n;" "#include \"overworld.HC\";;\n",__DIR__); while(TaskValidate(c)) Sleep(1000); #else OverWorldClient("../Untitled.WORLD.Z"); #endif BD1kcm   Db  d@task_end_cb=&MusicSettingsRst; music.mute++; I64 ohi=s->hi,olo=s->lo; while(--s->repeat>=0) { s->lo=olo; s->hi=ohi; F64 t=tS,e=t+ToF64(s->duration)/1000,cur=t; F64 next_dec=1./(s->freq)+t; for(;cur=next_dec) { next_dec=1./(s->freq)+cur; s->hi*=s->dampening; s->lo*=s->dampening; } Snd(s->lo+(s->hi-s->lo)*Caw(cur-t,1./s->freq)); Sleep(1); } } Snd; music.mute--; } CTask *ShitSound(I64 duration,I64 freq,I64 lo,I64 hi,F64 dampening=.9,I64 repeat=1) { CShitSound *s=AMAlloc(sizeof CShitSound); s->duration=duration,s->freq=freq,s->lo=lo,s->hi=hi; s->dampening=dampening; s->repeat=repeat; return Spawn(&ShitSoundTask,s); } #exe {Cd(__DIR__);;};; #define LOBBY_SERVER #include "frogs"; class CWAVFile { U8 RIFF[4]; U32 size; U8 WAVE[4]; U8 fmt[4]; U32 head_len; //16 U16 fmt_type; U16 num_channels; U32 sample_rate; U32 bytes_per_second; U16 byte_rate,bit_per_sample; U0 sub_chunk; }; F64 GetSample(U8 **at,I64 bps,I64 c) { F64 ret; switch(bps/c) { case 1: ret=ToF64(at[0](U8*)[0])/I8_MAX; break; case 2: ret=ToF64(at[0](I16*)[0])/I16_MAX; break; case 4: ret=ToF64(at[0](I32*)[0])/I32_MAX; break; } *at=at[0]+bps; return ret; } #define DOWNSAMPLE_FREQ 100. U64 BestOna(I8 *samps,I64 len) { F64 samp_amp,avg,last=0; I64 s=0; while(sRIFF,"RIFF",4)) { PrintErr("RIFF not found!\n"); poop: Free(wav); throw('WAV'); } if(wav->size!=fsz-8) { PrintErr("File size mismatch(%X bytes difference)\n",fsz-wav->size-8); goto poop; } if(StrNCmp(wav->WAVE,"WAVE",4)) { PrintErr("WAVE not found!\n"); goto poop; } if(StrNCmp(wav->fmt,"fmt ",4)) { PrintErr("fmt_ not found(got %s)!\n",wav->fmt); goto poop; } if(wav->head_len!=0x10) { PrintErr("Head not found!\n"); goto poop; } f=wav->sample_rate; c=wav->num_channels; bps=wav->byte_rate; ret=MAlloc(fsz/bps); ptr=&wav->sub_chunk; s=0; sub_chunk_loop: if(ptr(U8*)-wav(U8*)