import "std.zh" import "string.zh" import "ffcscript.zh" const int TL_A_BUTTON = 160; const int DMF_DARK = 0x0800; //DMF_SCRIPT1 const int DMF_OUTSIDE = 0x1000; //DMF_SCRIPT2 const int DMF_UNDERWATER = 0x2000; //DMF_SCRIPT3 const int TL_SNOW = 15056; const int TW_SNOW = 4; const int TAS_SNOW = 10; const int CB_TRANS = 1; const int CB_DARK = 37; const int CB_STATIC = 5904; const int TL_JINX = 25036; const int CT_LIGHT = 142; //CT_SCRIPT1 const int RAD_CANDLE1 = 32; const int RAD_CANDLE2 = 64; const int RAD_TILE = 32; const int LIGHT_EXPAND_TIME = 30; const int LIGHT_CONTRACT_TIME = 10; const int DARK_MAP = 4; const int DARK_SCREEN = 0x00; const int I_HOVER_SLIPPERS = 123; const int I_SMALL_SHIELD = 124; const int I_MAGIC_SHIELD = 125; const int I_MIRROR_SHIELD = 126; const int I_SWORDICON1 = 128; const int I_SWORDICON2 = 129; const int I_SWORDICON3 = 130; const int I_SWORDICON4 = 131; const int TL_SHADOW = 184; import "freshlist.zh" import "Scripts/noaction.zh" import "Scripts/interactable.zh" import "Scripts/menu.zh" import "Scripts/keyblock.zh" import "Scripts/itemmessage.zh" import "Scripts/itemupgrades.zh" import "Scripts/invistile.zh" import "Scripts/conditions.zh" import "Scripts/savestatue.zh" import "Scripts/conversations.zh" import "Scripts/goriya.zh" import "Scripts/goriya2.zh" import "Scripts/slidepuzzle.zh" import "Scripts/castle.zh" import "Scripts/ending.zh" import "Scripts/dragon.zh" int frame = 0; int snow_intensity = -2; int next_conversation = -1; int time_till_conversation = 0; int password[9]; int coversations_played[64]; bool eoiv_room_nw[176]; bool eoiv_room_ne[176]; bool eoiv_room_sw[176]; bool eoiv_room_se[176]; import "Scripts/password.zh" //CONVERSATION CONSTANTS (global since not enough stack space.....) int d00[] = "Help..."; int d01[] = "Please..."; int d02[] = "Help me..."; int d10[] = "Traveler..."; int d11[] = "If you can hear me..."; int d12[] = "Please come save me!"; int d20[] = "Hello...?"; int d21[] = "Please hurry..."; int d30[] = "I'm all alone..."; int d31[] = "I'm so scared..."; int d40[] = "Please listen..."; int d41[] = "I need your help..."; int d50[] = "..............."; int d51[] = "Can you hear me?"; int d52[] = "I'm losing hope..."; int d100[] = "I'm being held"; int d101[] = "against my will..."; int d102[] = "I'm at the top"; int d103[] = "of the castle..."; int d110[] = "If you save me..."; int d111[] = "I can help you find"; int d112[] = "what you are looking for."; int d120[] = "I've been alone"; int d121[] = "for so long..."; int d122[] = "Do your best!"; int d130[] = "I know it's hard..."; int d131[] = "But you can do it!"; int d132[] = "Don't go somewhere"; int d133[] = "if it seems impossible."; int d140[] = "The monsters around here"; int d141[] = "can be pretty scary..."; int d142[] = "Stay strong!"; int d150[] = "Keep searching..."; int d151[] = "I know you can"; int d152[] = "find some way forward!"; int d200[] = "Only those who"; int d201[] = "have a strong faith"; int d202[] = "can hear me..."; int d203[] = "You must be the one"; int d204[] = "who can rescue me!"; int d210[] = "This little island"; int d211[] = "used to be a much more"; int d212[] = "peaceful place..."; int d213[] = "But my captors..."; int d214[] = "They brought monsters"; int d215[] = "who now roam free."; int d220[] = "It seems like you are"; int d221[] = "making good progress!"; int d222[] = "Keep getting stronger!"; int d230[] = "It's been lonely here."; int d231[] = "I'm so glad someone"; int d232[] = "has finally come for me!"; int d240[] = "I wish I could be"; int d241[] = "of more help to you..."; int d242[] = "All I can offer is"; int d243[] = "continued encouragement."; int d244[] = "Good luck!!!"; int d250[] = "This island is a"; int d251[] = "confusing place..."; int d252[] = "Stay vigilant and"; int d253[] = "sort through the lies!"; int d254[] = "I believe you can find"; int d255[] = "a way to the castle!"; int dSA0[] = "Whew...!"; int dSA1[] = "That was a close one."; int dSA2[] = "You..."; int dSA3[] = "You're kinda cool!"; int dSB0[] = "Wow...!"; int dSB1[] = "You're quite skilled!"; int dSB2[] = "You..."; int dSB3[] = "You're really cool!"; int dSC0[] = "No way!!"; int dSC1[] = "You took care of that"; int dSC2[] = "like it was nothing!"; int dSC3[] = "You're awesome!!!"; int d300[] = "I believe you can do it!"; int d301[] = "Don't be daunted by"; int d302[] = "this castle's size,"; int d303[] = "or the many monsters."; int d304[] = "Keep trying your best,"; int d305[] = "and I know you will"; int d306[] = "be able to save me!"; int d310[] = "I've been trying to"; int d311[] = "speak to that"; int d312[] = "stupid shopkeeper"; int d313[] = "for quite a while now."; int d314[] = "But he just can't"; int d315[] = "hear me at all."; int d320[] = "No other travelers"; int d321[] = "have been able to"; int d322[] = "hear me either."; int d323[] = "You are the only one."; int d324[] = "Your faith is strong!"; int d330[] = "I love that sound when"; int d331[] = " Swoosh! "; int d332[] = "you slash your sword."; int d333[] = "I bet you could put out"; int d334[] = "a small fire with the wind."; int d340[] = "This castle..."; int d341[] = "I heard a great king"; int d342[] = "once ruled here."; int d343[] = "His name was..."; int d344[] = "Well, I don't remember."; int d345[] = "I guess it isn't important."; int d350[] = "You've been fighting hard"; int d351[] = "for quite a while now."; int d352[] = "Make sure to take a break"; int d353[] = "to save up your strength!"; int d400[] = "The knights around here"; int d401[] = "sure are annoying..."; int d402[] = "Sigh..."; int d403[] = "Sorry, was that weird?"; int d404[] = "I have this odd habit"; int d405[] = "of actually saying"; int d406[] = "sigh instead of sighing."; int d410[] = "I hope you aren't"; int d411[] = "finding me irritating..."; int d412[] = "It's been so long since"; int d413[] = "I've had someone"; int d414[] = "to talk to."; int d415[] = "And I want to do my best"; int d416[] = "to keep you company too."; int d420[] = "Have you been wondering"; int d421[] = "why I was captured?"; int d422[] = "Where I come from,"; int d423[] = "I was greatly hated"; int d424[] = "because I was different."; int d425[] = "Many awful people"; int d426[] = "left me here to die."; int d430[] = "I'm sure you've noticed,"; int d431[] = "I have some magic power."; int d432[] = "So, I have managed"; int d433[] = "to survive here."; int d434[] = "But I cannot escape"; int d435[] = "because a dreadful dragon"; int d436[] = "guards my room."; int d440[] = "Have you been wondering"; int d441[] = "why the lava here"; int d442[] = "does not produce light?"; int d443[] = "I honestly have no clue."; int d450[] = "There are many neat"; int d451[] = "things in this castle."; int d452[] = "I'm sure a lot of magical"; int d453[] = "research was required"; int d454[] = "to make it all."; int d500[] = "Oh! Those slippers!"; int d501[] = "They were taken from me."; int d502[] = "Of course, I don't mind"; int d503[] = "seeing you use them."; int d504[] = "Actually... They look"; int d505[] = "pretty cute on you."; int d510[] = "Say, when this is over"; int d511[] = "do you think we"; int d512[] = "could be friends?"; int d513[] = "You think I'm getting"; int d514[] = "ahead of myself?"; int d515[] = "But by now, I have"; int d516[] = "no doubt in my mind"; int d517[] = "that you will find me!"; int d6000[] = "You know, it's been"; int d6001[] = "quite a while since I"; int d6002[] = "last felt the snow."; int d6003[] = "Even though it's"; int d6004[] = "cold and wet,"; int d6005[] = "I really like how"; int d6006[] = "fluffy and soft it is!"; int d6007[] = "And the snow is so"; int d6008[] = "pretty when it falls!"; int d6009[] = "Seeing a pure white"; int d6010[] = "blanket of snow"; int d6011[] = "just makes me want to"; int d6012[] = "wrap myself in it"; int d6013[] = "and take a relaxing"; int d6014[] = "super comfy nap."; int d6015[] = "I can't wait to"; int d6016[] = "feel the snow again."; int d6017[] = "Sigh..."; int d6018[] = "........."; int d6019[] = "Sorry..."; int d6020[] = "I'm totally rambling"; int d6021[] = "aren't I?"; int d6022[] = "Um... Well, I think"; int d6023[] = "you've almost made it!"; int d6024[] = "Good luck!"; int d6100[] = "Do you enjoy stories?"; int d6101[] = "I am suddenly reminded"; int d6102[] = "of a story I read when"; int d6103[] = "I was younger."; int d6104[] = "It was titled:"; int d6105[] = " To The Top. "; int d6106[] = "Well, the story was"; int d6107[] = "honestly pretty bad,"; int d6108[] = "but here you are,"; int d6109[] = "climbing to the top"; int d6110[] = "of this castle."; int d6111[] = "I can't wait to meet you!"; int d6200[] = "This island must have"; int d6201[] = "a dedicated caretaker."; int d6202[] = "I mean, the grass and"; int d6203[] = "bushes grow back"; int d6204[] = "unbelievably fast."; int d6205[] = "And the pots you break"; int d6206[] = "are quickly replaced."; int d6207[] = "Although I've never"; int d6208[] = "seen such a person..."; int d6209[] = "Could it be one of..."; int d6210[] = "One of the m-monsters?"; int d6211[] = "Make sure not to kill"; int d6212[] = "that one, okay?"; int d6213[] = "Hmm..."; int d6214[] = "On second thought, it's"; int d6215[] = "probably just magic."; //KEY BLOCK CONSTANTS (global since not enough stack space.....) // //pushy cave entry // int k00[] = {4, 0x31, 65}; // int k01[] = {4, 0x31, 32}; // int k02[] = {4, 0x30, 47}; int kb0[] = {4, 0x31, 65, 4, 0x31, 32, 4, 0x30, 47}; // //pushy cave back // int k10[] = {4, 0x20, 30}; // int k11[] = {4, 0x20, 63}; // int k12[] = {4, 0x21, 48}; int kb1[] = {4, 0x20, 30, 4, 0x20, 63, 4, 0x21, 48}; // //underwater entry up // int k20[] = {4, 0x54, 17}; // int k21[] = {4, 0x54, 3}; // int k22[] = {4, 0x44, 163}; int kb2[] = {4, 0x54, 17, 4, 0x54, 3, 4, 0x44, 163}; // //underwater entry right // int k30[] = {4, 0x54, 62}; // int k31[] = {4, 0x54, 95}; // int k32[] = {4, 0x55, 80}; int kb3[] = {4, 0x54, 62, 4, 0x54, 95, 4, 0x55, 80}; // //underwater back // int k40[] = {4, 0x44, 45}; // int k41[] = {4, 0x44, 95}; // int k42[] = {4, 0x45, 80}; int kb4[] = {4, 0x44, 45, 4, 0x44, 95, 4, 0x45, 80}; // //sword cave left // int k50[] = {4, 0x26, 113}; // int k51[] = {4, 0x26, 47}; // int k52[] = {4, 0x27, 32}; int kb5[] = {4, 0x26, 113, 4, 0x26, 47, 4, 0x27, 32}; // //sword cave right // int k60[] = {4, 0x28, 93}; // int k61[] = {4, 0x28, 81}; // int k62[] = {4, 0x27, 95}; int kb6[] = {4, 0x28, 93, 4, 0x28, 81, 4, 0x27, 95}; // //garden left // int k70[] = {2, 0x26, 132}; // int k71[] = {2, 0x26, 71}; // int k72[] = {2, 0x26, 72}; int kb7[] = {2, 0x26, 132, 2, 0x26, 71, 2, 0x26, 72}; // //garden right // int k80[] = {2, 0x26, 124}; // int k81[] = {2, 0x26, 71}; // int k82[] = {2, 0x26, 72}; int kb8[] = {2, 0x26, 124, 2, 0x26, 71, 2, 0x26, 72}; // //prison w // int k90[] = {7, 0x01, 34}; // int k91[] = {7, 0x01, 60}; // int k92[] = {7, 0x01, 61}; int kb9[] = {7, 0x01, 34, 7, 0x01, 60, 7, 0x01, 61}; // //prison e // int k100[] = {7, 0x14, 45}; // int k101[] = {8, 0x14, 58}; // int k102[] = {9, 0x14, 58}; int kb10[] = {7, 0x14, 45, 8, 0x14, 58, 9, 0x14, 58}; // //castle f1 e // int k110[] = {7, 0x29, 137}; // int k111[] = {7, 0x29, 151}; // int k112[] = {7, 0x39, 23}; // int k113[] = {9, 0x29, 151}; // int k114[] = {9, 0x39, 23}; int kb11[] = {7, 0x29, 137, 7, 0x29, 151, 7, 0x39, 23, 9, 0x29, 151, 9, 0x39, 23}; // //castle f1 nw // int k120[] = {7, 0x16, 130}; // int k121[] = {7, 0x16, 27}; // int k122[] = {7, 0x06, 171}; int kb12[] = {7, 0x16, 130, 7, 0x16, 27, 7, 0x06, 171}; // //castle f1 se // int k130[] = {7, 0x48, 45}; // int k131[] = {7, 0x48, 115}; // int k132[] = {10, 0x43, 115}; int kb13[] = {7, 0x48, 45, 7, 0x48, 115, 10, 0x43, 115}; // //castle f2 nw // int k140[] = {10, 0x02, 51}; // int k141[] = {10, 0x02, 71}; // int k142[] = {10, 0x02, 72}; int kb14[] = {10, 0x02, 51, 10, 0x02, 71, 10, 0x02, 72}; //castle f2 ne // int k150[] = {10, 0x02, 124}; // int k151[] = {10, 0x02, 71}; // int k152[] = {10, 0x02, 72}; int kb15[] = {10, 0x02, 124, 10, 0x02, 71, 10, 0x02, 72}; //castle f2 sm dorm int kb16[] = {10, 0x42, 98, 10, 0x42, 124, 10, 0x47, 124}; //castle f2 se int kb17[] = {10, 0x43, 34, 10, 0x43, 81, 10, 0x42, 94}; //castle f3 n int kb18[] = {10, 0x07, 145, 10, 0x07, 168, 10, 0x17, 8}; //castle f3 nm int kb19[] = {10, 0x17, 44, 10, 0x17, 49, 10, 0x16, 62}; //castle f3 w int kb20[] = {10, 0x35, 34, 10, 0x35, 91, 10, 0x35, 115, 10, 0x3A, 115}; //castle f3 sm corridor // int k210[] = {10, 0x37, 62}; // int k211[] = {10, 0x37, 126}; // int k212[] = {10, 0x38, 113}; int kb21[] = {10, 0x37, 62, 10, 0x37, 126, 10, 0x38, 113}; // //castle f3 sw dorm // int k220[] = {10, 0x46, 130}; // int k221[] = {10, 0x46, 24}; // int k222[] = {10, 0x36, 152}; int kb22[] = {10, 0x46, 130, 10, 0x46, 24, 10, 0x36, 152}; //castle f3 sm dorm int kb23[] = {10, 0x47, 34, 10, 0x47, 94, 10, 0x48, 81}; //castle f3 se dorm int kb24[] = {10, 0x48, 138, 10, 0x48, 124, 10, 0x4D, 124}; //castle f4 sm int kb31[] = {10, 0x3C, 45, 10, 0x3C, 23, 10, 0x3C, 24, 10, 0x2C, 151, 10, 0x2C, 152}; //castle outside e not set int kb33[] = {10, 0x1E, 106, 10, 0x1E, 53, 10, 0x1E, 69, 10, 0x1E, 73, 10, 0x1E, 86, 10, 0x1E, 88, 10, 0x1E, 99, 10, 0x1E, 101, 10, 0x1E, 118, 10, 0x1E, 124, 10, 0x1E, 133, 10, 0x1E, 167, 10, 0x1E, 168}; //castle outside e set int kb35[] = {10, 0x1E, 51, 10, 0x1E, 53, 10, 0x1E, 69, 10, 0x1E, 73, 10, 0x1E, 86, 10, 0x1E, 88, 10, 0x1E, 99, 10, 0x1E, 101, 10, 0x1E, 118, 10, 0x1E, 124, 10, 0x1E, 133, 10, 0x1E, 167, 10, 0x1E, 168}; //castle tower entrance int kb34[] = {10, 0x4C, 68, 10, 0x4C, 55, 10, 0x4C, 56}; global script AllGlobals { void run() { //FIRST BOOT INITIALIZATION if(password[0] == 0) { //password initialization for(int i = 0; i < 8; i++) { password[i] = Cond(Choose(0, 1) == 1, '0' + Rand(1,9), 'A' + Rand(0,25)); } password[8] = 0; //Set the key block on the castle top to have a key in it already key_blocks_active[35] = true; //Set initial magic warp shooters' directions Game->SetDMapScreenD(25, 0x20, 0, DIR_UP); Game->SetDMapScreenD(25, 0x20, 1, DIR_DOWN); Game->SetDMapScreenD(22, 0x33, 0, DIR_LEFT); Game->SetDMapScreenD(26, 0x31, 0, DIR_UP); Game->SetDMapScreenD(26, 0x31, 1, DIR_RIGHT); Game->SetDMapScreenD(26, 0x31, 2, DIR_LEFT); } //FIRST BOOT INITIALIZATION //KEY BLOCK INITIALIZATION // int kb0[] = {k00, k01, k02}; // int kb1[] = {k10, k11, k12}; // int kb2[] = {k20, k21, k22}; // int kb3[] = {k30, k31, k32}; // int kb4[] = {k40, k41, k42}; // int kb5[] = {k50, k51, k52}; // int kb6[] = {k60, k61, k62}; // int kb7[] = {k70, k71, k72}; // int kb8[] = {k80, k81, k82}; // int kb9[] = {k90, k91, k92}; // int kb10[] = {k100, k101, k102}; // int kb11[] = {k110, k111, k112, k113, k114}; // int kb12[] = {k120, k121, k122}; // int kb13[] = {k130, k131, k132}; // int kb14[] = {k140, k141, k142}; // int kb15[] = {k150};//, k151, k152}; // int kb21[] = {k210};//, k211, k212}; // // int kb22[] = {k220, k221, k222}; //castle f4 boss key nw int kb25[] = {10, 0x1B, 34, 10, 0x1B, 55, 10, 0x1B, 72}; //castle f4 boss key nw int kb26[] = {10, 0x1B, 45, 10, 0x1B, 56, 10, 0x1B, 71}; //castle f4 boss key nw int kb27[] = {10, 0x1B, 130, 10, 0x1B, 86, 10, 0x1B, 88}; //castle f4 boss key nw int kb28[] = {10, 0x1B, 141, 10, 0x1B, 87, 10, 0x1B, 89}; //castle f4 se int kb30[] = {10, 0x2D, 132, 10, 0x2D, 28, 10, 0x1D, 156}; //castle f4 se int kb32[] = {10, 0x3D, 141, 10, 0x3D, 28, 10, 0x2D, 156}; int temp_events[] = {kb0, kb1, kb2, kb3, kb4, kb5, kb6, kb7, kb8, kb9, kb10, kb11, kb12, kb13, kb14, kb15, kb16, kb17, kb18, kb19, kb20, kb21, kb22, kb23, kb24, kb25, kb26, kb27, kb28, 0, kb30, kb31, kb32, kb33, kb34, kb35}; key_block_events = temp_events; //make sure to reopen all unlocked blocks upon game load for(int id = 0; id < 64; id++) { if(key_blocks_active[id]) { toggle_key_block_events(id, 1); } } //KEY BLOCK INITIALIZATION //CHSET GAG INITIALIZATION chest_gag_initialization(); //CHSET GAG INITIALIZATION //SLIDE PUZZLE INITIALIZATION slide_puzzle_initialization(); //SLIDE PUZZLE INITIALIZATION //MAGIC WARP INITIALIZATION magic_warp_initialization(); //MAGIC WARP INITIALIZATION //EOIV ROOM INITIALIZATION eoiv_initialization(); //EOIV ROOM INITIALIZATION //PIT SHORTCUT INITIALIZATION pitshortcut_initialization(); //PIT SHORTCUT INITIALIZATION //CONVERSATION INITIALIZATION //constructs all conversations, putting the result into the conversations //when creating new conversations, always add to the end //this has to be done here so that the arrays persist, but are not saved to the game file //quotation marks d331[0] = 34; d331[8] = 34; d6105[0] = 34; d6105[12] = 34; int dialog0[] = {d00, d01, d02}; int convo0[] = {COND_TRUE, COND_FALSE, COND_IN_PUSHY_CAVE, 0, 60 * 60 * 2, 35, 4, dialog0}; int dialog1[] = {d10, d11, d12}; int convo1[] = {COND_TRUE, COND_HAVE_PUSHY, COND_FALSE, 1, 60 * 60 * 2, 35, 4, dialog1}; int dialog2[] = {d20, d21}; int convo2[] = {COND_TRUE, COND_HAVE_PUSHY, COND_FALSE, 2, 60 * 60 * 3, 35, 4, dialog2}; int dialog3[] = {d30, d31}; int convo3[] = {COND_TRUE, COND_HAVE_PUSHY, COND_FALSE, 3, 60 * 60 * 4, 35, 4, dialog3}; int dialog4[] = {d40, d41}; int convo4[] = {COND_TRUE, COND_HAVE_PUSHY, COND_FALSE, 4, 60 * 60 * 5, 35, 4, dialog4}; int dialog5[] = {d50, d51, d52}; int convo5[] = {COND_TRUE, COND_HAVE_PUSHY, COND_FALSE, 5, 60 * 60 * 6, 35, 4, dialog5}; int dialog10[] = {d100, d101, d102, d103}; int convo10[] = {COND_HAVE_PUSHY, COND_FALSE, COND_HAVE_MUSH_OR_BAG, 10, 60 * 60 * 2, 30, 5, dialog10}; int dialog11[] = {d110, d111, d112}; int convo11[] = {COND_HAVE_PUSHY, COND_FALSE, COND_HAVE_MUSH_AND_BAG, 11, 60 * 60 * 2, 30, 5, dialog11}; int dialog12[] = {d120, d121, d122}; int convo12[] = {COND_HAVE_PUSHY, COND_HAVE_BOMBS, COND_FALSE, 12, 60 * 60 * 3, 30, 5, dialog12}; int dialog13[] = {d130, d131, d132, d133}; int convo13[] = {COND_HAVE_PUSHY, COND_HAVE_BOMBS, COND_HAVE_SWORD, 13, 60 * 60 * 4, 30, 5, dialog13}; int dialog14[] = {d140, d141, d142}; int convo14[] = {COND_HAVE_PUSHY, COND_HAVE_BOMBS, COND_HAVE_SWORD, 14, 60 * 60 * 5, 30, 5, dialog14}; int dialog15[] = {d150, d151, d152}; int convo15[] = {COND_HAVE_PUSHY, COND_HAVE_BOMBS, COND_HAVE_SWORD, 15, 60 * 60 * 6, 30, 5, dialog15}; int dialog20[] = {d200, d201, d202, d203, d204}; int convo20[] = {COND_HAVE_BOMBS, COND_FALSE, COND_FALSE, 20, 60 * 60 * 2, 25, 6, dialog20}; int dialog21[] = {d210, d211, d212, d213, d214, d215}; int convo21[] = {COND_HAVE_BOMBS, COND_FALSE, COND_FALSE, 21, 60 * 60 * 3, 25, 6, dialog21}; int dialog22[] = {d220, d221, d222}; int convo22[] = {COND_HAVE_TWO_KEYS, COND_HAVE_SWORD, COND_FALSE, 22, 60 * 60 * 3, 25, 6, dialog22}; int dialog23[] = {d230, d231, d232}; int convo23[] = {COND_HAVE_TWO_KEYS, COND_HAVE_SWORD, COND_ENTERED_CASTLE, 23, 60 * 60 * 4, 25, 6, dialog23}; int dialog24[] = {d240, d241, d242, d243, d244}; int convo24[] = {COND_HAVE_TWO_KEYS, COND_HAVE_SWORD, COND_ENTERED_CASTLE, 24, 60 * 60 * 5, 25, 6, dialog24}; int dialog25[] = {d250, d251, d252, d253, d254, d255}; int convo25[] = {COND_HAVE_TWO_KEYS, COND_HAVE_SWORD, COND_ENTERED_CASTLE, 25, 60 * 60 * 5, 25, 6, dialog25}; int dialogSA[] = {dSA0, dSA1, dSA2, dSA3}; int convoSA[] = {COND_BEAT_GORIYA_NORM, COND_FALSE, COND_FALSE, 19, 60, 20, 8, dialogSA}; int dialogSB[] = {dSB0, dSB1, dSB2, dSB3}; int convoSB[] = {COND_BEAT_GORIYA_THREE, COND_FALSE, COND_FALSE, 18, 60, 20, 8, dialogSB}; int dialogSC[] = {dSC0, dSC1, dSC2, dSC3}; int convoSC[] = {COND_BEAT_GORIYA_LOW, COND_FALSE, COND_FALSE, 17, 60, 20, 8, dialogSC}; int dialog30[] = {d300, d301, d302, d303, d304, d305, d306}; int convo30[] = {COND_ENTERED_CASTLE, COND_HOVER_SLIPPERS, COND_FALSE, 30, 60 * 60 * 2, 15, 10, dialog30}; int dialog31[] = {d310, d311, d312, d313, d314, d315}; int convo31[] = {COND_ENTERED_CASTLE, COND_HOVER_SLIPPERS, COND_FALSE, 31, 60 * 60 * 4, 15, 10, dialog31}; int dialog32[] = {d320, d321, d322, d323, d324}; int convo32[] = {COND_ENTERED_CASTLE, COND_HOVER_SLIPPERS, COND_FALSE, 32, 60 * 60 * 4, 15, 10, dialog32}; int dialog33[] = {d330, d332, d331, d333, d334}; int convo33[] = {COND_ENTERED_CASTLE, COND_FALSE, COND_FALSE, 50, 60 * 60 * 6, 15, 10, dialog33}; int dialog34[] = {d340, d341, d342, d343, d344, d345}; int convo34[] = {COND_ENTERED_CASTLE, COND_FALSE, COND_FALSE, 53, 60 * 60 * 7, 15, 10, dialog34}; int dialog35[] = {d350, d351, d352, d353}; int convo35[] = {COND_ENTERED_CASTLE, COND_FALSE, COND_FALSE, 55, 60 * 60 * 8, 15, 10, dialog35}; int dialog40[] = {d400, d401, d402, d403, d404, d405, d406}; int convo40[] = {COND_AMULET_OR_FIVE_KEYS, COND_HOVER_SLIPPERS, COND_FALSE, 40, 60 * 60 * 3, 15, 10, dialog40}; int dialog41[] = {d410, d411, d412, d413, d414, d415, d416}; int convo41[] = {COND_AMULET_OR_FIVE_KEYS, COND_HOVER_SLIPPERS, COND_FALSE, 41, 60 * 60 * 4, 15, 10, dialog41}; int dialog42[] = {d420, d421, d422, d423, d424, d425, d426}; int convo42[] = {COND_AMULET_OR_FIVE_KEYS, COND_FALSE, COND_FALSE, 51, 60 * 60 * 6, 15, 10, dialog42}; int dialog43[] = {d430, d431, d432, d433, d434, d435, d436}; int convo43[] = {COND_AMULET_OR_FIVE_KEYS, COND_FALSE, COND_FALSE, 52, 60 * 60 * 7, 15, 10, dialog43}; int dialog44[] = {d440, d441, d442, d443}; int convo44[] = {COND_AMULET_OR_FIVE_KEYS, COND_FALSE, COND_FALSE, 54, 60 * 60 * 8, 15, 10, dialog44}; int dialog45[] = {d450, d451, d452, d453, d454}; int convo45[] = {COND_AMULET_OR_FIVE_KEYS, COND_FALSE, COND_FALSE, 56, 60 * 60 * 8, 15, 10, dialog45}; int dialog50[] = {d500, d501, d502, d503, d504, d505}; int convo50[] = {COND_HOVER_SLIPPERS, COND_HAVE_BOOMERANG, COND_FALSE, 45, 60 * 60 * 2, 10, 12, dialog50}; int dialog51[] = {d510, d511, d512, d513, d514, d515, d516, d517}; int convo51[] = {COND_HOVER_SLIPPERS, COND_HAVE_BOOMERANG, COND_FALSE, 46, 60 * 60 * 3, 10, 12, dialog51}; int dialog60[] = {d6000, d6001, d6002, d6003, d6004, d6005, d6006, d6007, d6008, d6009, d6010, d6011, d6012, d6013, d6014, d6015, d6016, d6017, d6018, d6019, d6020, d6021, d6022, d6023, d6024}; int convo60[] = {COND_HAVE_BOOMERANG, COND_FALSE, COND_FALSE, 47, 60 * 60 * 1, 6, 20, dialog60}; int dialog61[] = {d6100, d6101, d6102, d6103, d6104, d6105, d6106, d6107, d6108, d6109, d6110, d6111}; int convo61[] = {COND_HAVE_BOOMERANG, COND_FALSE, COND_FALSE, 61, 60 * 60 * 8, 6, 20, dialog61}; int dialog62[] = {d6200, d6201, d6202, d6203, d6204, d6205, d6206, d6207, d6208, d6209, d6210, d6211, d6212, d6213, d6214, d6215}; int convo62[] = {COND_HAVE_BOOMERANG, COND_FALSE, COND_FALSE, 60, 60 * 60 * 6, 6, 20, dialog62}; int conversations[] = {convo0, convo1, convo2, convo3, convo4, convo5, convo10, convo11, convo12, convo13, convo14, convo15, convo20, convo21, convo22, convo23, convo24, convo25, convoSA, convoSB, convoSC, convo30, convo31, convo32, convo33, convo34, convo35, convo40, convo41, convo42, convo43, convo44, convo45, convo50, convo51, convo60, convo61, convo62}; //CONVERSATION INITIALIZATON int transition = 0; int transition_dir = 0; int prev_screen = 0; int prev_dmap = 0; int text_length = 0; int dialog_index = 0; int string_end_wait = 0; int strafing = 0; int strafe_dir = 0; bool text_static[980]; int lightsCapacity = 254; int lightsX[256]; int lightsY[256]; int lightsT[256]; int lightsR[256]; int flist[2]; bool fdata[256]; bool idsFound[256]; int lightsLinkTimer = 0; int lightsLinkMaxTimer = 0; FListInit(flist, fdata, lightsCapacity); bool prevDark = true; int boomerflamesX[] = {-1, -1, -1, -1, -1}; int boomerflamesY[] = {-1, -1, -1, -1, -1}; lweapon brang; //in flight bool brangInFlight = false; int curEquipmentB; int prevEquipmentB; //int enemyFlagCounts[10]; int enemyFlagCounts[5]; int en0[176]; int en1[176]; int en2[176]; int en3[176]; int en4[176]; //int en5[176]; int en6[176]; int en7[176]; int en8[176]; int en9[176]; int eni; //int flagPositions[] = {en0, en1, en2, en3, en4, en5, en6, en7, en8, en9}; int flagPositions[] = {en0, en1, en2, en3, en4}; int prevLinkY = Link->Y; while(1) { //RANDOM ENEMY SPAWNS if(prev_screen != Game->GetCurScreen() || prev_dmap != Game->GetCurDMap()) { //count the number of occurrences of each enemy placement flag //for(int i = 0; i < 10; i++) for(int i = 0; i < 5; i++) { enemyFlagCounts[i] = 0; } for(int i = 0; i < 176; i++) { int curFlag = Screen->ComboF[i] - 37; //if(curFlag >= 0 && curFlag <= 9) if(curFlag >= 0 && curFlag <= 4) { eni = flagPositions[curFlag]; eni[(enemyFlagCounts[curFlag])] = i; enemyFlagCounts[curFlag]++; } } //remove all but one of the flags, randomly //for(int i = 0; i < 10; i++) for(int i = 0; i < 5; i++) { //check that there are any Enemy i flags to begin with if(enemyFlagCounts[i] > 0) { //pick a flag to keep eni = flagPositions[i]; int flagToKeep = Rand(0, enemyFlagCounts[i] - 1); //remove all other Enemy i flags for(int j = 0; j < enemyFlagCounts[i]; j++) { if(j != flagToKeep) { Screen->ComboF[eni[j]] = CF_NONE; } } } } } //RANDOM ENEMY SPAWNS //GET PERTINENT GAME INFO curEquipmentB = GetEquipmentB(); if(transition > 0) { transition--; } if(!(Link->X > 0 && Link->X < 241 && Link->Y > 0 && Link->Y < 161) && transition == 0) { if(Link->Y == 176) { transition_dir = DIR_UP; transition = 44; } if(Link->Y == -16) { transition_dir = DIR_DOWN; transition = 44; } if(Link->X == -16) { transition_dir = DIR_RIGHT; transition = 64; } if(Link->X == 256) { transition_dir = DIR_LEFT; transition = 64; } } if(transition == 0) { prev_screen = Game->GetCurScreen(); prev_dmap = Game->GetCurDMap(); } brangInFlight = false; lweapon next_weapon; for(int i = 1; i <= Screen->NumLWeapons(); ++i) { next_weapon = Screen->LoadLWeapon(i); if(next_weapon->ID == LW_BRANG) { brang = next_weapon; brangInFlight = true; } } //GET PERTINENT GAME INFO END //SNOW EFFECT // //upon entering an outside dmap, mark that you are outside // if(!outside) // { // if(GetDMapFlag(Game->GetCurDMap(), DMF_OUTSIDE)) // { // outside = true; // //depending on the time, it can start or continue snowing // if((((frame / 3600) << 0) % 2) == 1) // { // snowing = true; // } // } // } // //going inside marks that you are inside, and it of course stops snowing // else // { // if(!GetDMapFlag(Game->GetCurDMap(), DMF_OUTSIDE)) // { // outside = false; // snowing = false; // } // } //chance of increasing or decreasing snow intensity every 5 seconds if((frame % 500) == 0) { int rand_change = Rand(5); int delta = 0; if(rand_change == 0) delta = -1; if(rand_change == 4) delta = 1; snow_intensity = Min(4, Max(-2, snow_intensity + delta)); } //display snow effect //if(snowing) if(GetDMapFlag(Game->GetCurDMap(), DMF_OUTSIDE)) { int x_off = 0; int y_off = 0; if(transition_dir == DIR_LEFT) x_off = -256 * (transition / 64); if(transition_dir == DIR_RIGHT) x_off = 256 * (transition / 64); if(transition_dir == DIR_UP) y_off = -176 * (transition / 44); if(transition_dir == DIR_DOWN) y_off = 176 * (transition / 44); for(int i = 0; i < 176; i++) { //Screen->FastTile(6, i % 16, i / 16, 15056 + ((frame / 10) % 4), 2, OP_OPAQUE); //This was wrong but funny if(snow_intensity == 1) { Screen->FastTile(6, (i % 16) * 16 + (x_off % 16), ((i / 16) << 0) * 16 + (y_off % 16), TL_SNOW + ((frame / TAS_SNOW) % TW_SNOW) + 16, 2, OP_OPAQUE); } if(snow_intensity == 2) { Screen->FastTile(6, (i % 16) * 16 + (x_off % 16), ((i / 16) << 0) * 16 + (y_off % 16), TL_SNOW + ((frame / TAS_SNOW) % TW_SNOW), 2, OP_OPAQUE); } if(snow_intensity == 3) { Screen->FastTile(6, (i % 16) * 16 + (x_off % 16), ((i / 16) << 0) * 16 + (y_off % 16), TL_SNOW + ((frame / TAS_SNOW) % TW_SNOW), 2, OP_OPAQUE); Screen->FastTile(6, (i % 16) * 16 + (x_off % 16) - 6, ((i / 16) << 0) * 16 + (y_off % 16) - 4, TL_SNOW + ((frame / (TAS_SNOW - 4)) % TW_SNOW), 2, OP_OPAQUE); } if(snow_intensity == 4) { Screen->FastTile(6, (i % 16) * 16 + (x_off % 16), ((i / 16) << 0) * 16 + (y_off % 16), TL_SNOW + ((frame / TAS_SNOW) % TW_SNOW), 2, OP_OPAQUE); Screen->FastTile(6, (i % 16) * 16 + (x_off % 16) - 6, ((i / 16) << 0) * 16 + (y_off % 16) - 4, TL_SNOW + ((frame / (TAS_SNOW - 4)) % TW_SNOW) - 4, 2, OP_OPAQUE); } } } //SNOW EFFECT END //Clouds? //Screen->DrawTile(6, -250 + (frame / 5) % 750, 65, 38220, 9, 4, 0, -1, -1, 0, 0, 0, 0, true, OP_TRANS); //Screen->DrawTile(6, -250 + (frame / 3) % 750, 35, 38220, 9, 4, 0, -1, -1, 0, 0, 0, 0, true, OP_TRANS); //DARK ROOM if(GetDMapFlag(Game->GetCurDMap(), DMF_DARK) || dragon_dark()) { prevDark = true; //if link opens the map, change the layer back to darkness so the screens are hidden on the map if(Link->PressMap && GetDMapFlag(Game->GetCurDMap(), DMF_VIEWMAP)) { NoActionPlus(); for(int i = 0; i < 176; i++) { Game->SetComboData(DARK_MAP, DARK_SCREEN, i, CB_DARK); } Link->InputMap = true; Waitframe(); } //make it so that layer 6 is transparent, the drawing will do all the work for darkness for(int i = 0; i < 176; i++) { Game->SetComboData(DARK_MAP, DARK_SCREEN, i, CB_TRANS); } //saving stack space womp ffc dragon; int cameraY; float darkness_x; float darkness_y; int darkness_t; //Set the render target to the bitmap. Screen->SetRenderTarget(1); //empty buffer Screen->Rectangle(5, 0, 0, 256, 176, 0x00, 1, 0, 0, 0, true, 128); //Draw a opaque rectangle to cover the entire screen. if(!dragon_dark()) { Screen->Rectangle(5, 0, 0, 256, 176, 0x08, 1, 0, 0, 0, true, 128); } //dragon darkness else { //get relevant shared variables dragon = Screen->LoadFFC(1); if(dragon->Misc[11] == 0) { cameraY = dragon->Misc[0]; darkness_x = dragon->Misc[3]; darkness_y = dragon->Misc[4]; darkness_t = dragon->Misc[5]; //dark circles for(int i = 0; i < 8; i++) { if(darkness_t[i] >= 400) { for(int c = 0; c < 3; c++){ float scale = (500 - darkness_t[i])/100; float angle = Randf(360); Screen->Circle(5, darkness_x[i] + scale* 8 * Cos(angle), darkness_y[i] + scale * 8 * Sin(angle) - cameraY, scale * 24, 0x08, 1, 0, 0, 0, true, OP_OPAQUE); } } else if(darkness_t[i] >= 0) { for(int c = 0; c < 3; c++){ float angle = Randf(360); Screen->Circle(5, darkness_x[i] + 8 * Cos(angle), darkness_y[i] + 8 * Sin(angle) - cameraY, 24, 0x08, 1, 0, 0, 0, true, OP_OPAQUE); } } } } //fill the room with darkness else { Screen->Rectangle(5, 0, 0, 256, 176, 0x08, 1, 0, 0, 0, true, 128); } } //Draw transparent black circles. "Must use color 0 of CSet 0 or it won't work right." for(int i = 0; i < lightsCapacity; i++) { idsFound[i] = false; } float radius_var = 1 + 0.05*Sin(frame * 5); if(transition == 0) { //Link float radius = 0; float calcedRadius = 0.0; if(curEquipmentB == I_CANDLE1) { radius = RAD_CANDLE1; lightsLinkMaxTimer = LIGHT_EXPAND_TIME; } if(curEquipmentB == I_CANDLE2) { radius = RAD_CANDLE2; lightsLinkMaxTimer = Floor((RAD_CANDLE2 / RAD_CANDLE1) * LIGHT_EXPAND_TIME); } if(curEquipmentB == I_BRANG3) { radius = RAD_CANDLE1; lightsLinkMaxTimer = LIGHT_EXPAND_TIME; } if(radius > 0) { if(lightsLinkTimer < lightsLinkMaxTimer && !brangInFlight) lightsLinkTimer++; else if(lightsLinkTimer < LIGHT_EXPAND_TIME) lightsLinkTimer++; if(lightsLinkTimer > lightsLinkMaxTimer) lightsLinkTimer--; calcedRadius = radius * radius_var * (lightsLinkTimer / lightsLinkMaxTimer); if(!brangInFlight) { Screen->Circle(5, Link->X + 8, Link->Y + 8, calcedRadius, 0, 1, 0, 0, 0, true, 128); } } else { if(!brangInFlight){ lightsLinkTimer = Max(lightsLinkTimer - 3, 0); //draw contracting circle if(lightsLinkTimer > 0) { if(Link->Item[I_CANDLE1]) { radius = RAD_CANDLE1; lightsLinkMaxTimer = LIGHT_EXPAND_TIME; } if(Link->Item[I_BRANG3]) { radius = RAD_CANDLE1; lightsLinkMaxTimer = LIGHT_EXPAND_TIME; } if(Link->Item[I_CANDLE2]) { radius = RAD_CANDLE2; lightsLinkMaxTimer = Floor((RAD_CANDLE2 / RAD_CANDLE1) * LIGHT_EXPAND_TIME); } calcedRadius = radius * radius_var * (lightsLinkTimer / lightsLinkMaxTimer); Screen->Circle(5, Link->X + 8, Link->Y + 8, calcedRadius, 0, 1, 0, 0, 0, true, 128); } } } //Lights for(int i = 0; i < 176; i++) { if(Screen->ComboT[i] == CT_LIGHT) { Screen->Circle(5, ((i % 16) * 16) + 8, (((i / 16) << 0) * 16) + 8, RAD_TILE * radius_var, 0, 1, 0, 0, 0, true, 128); } } //Shutter if((Screen->Flags[SF_MISC] & 4) == 4) { int closedness = Screen->D[0]; if(closedness < 32) { Screen->Rectangle(5, 96 - (64 - 2*closedness)*(1 - radius_var)/3 + closedness, 64 - 48*(1 - radius_var)/3, 160 + (64 - 2*closedness)*(1 - radius_var)/3 - closedness, 112 + 48*(1 - radius_var)/3, 0, 1, 0, 0, 0, true, OP_OPAQUE); } } //lweapon fire lweapon cur_weapon; radius = 0; for(int i = 1; i <= Screen->NumLWeapons(); ++i) { cur_weapon = Screen->LoadLWeapon(i); if(cur_weapon->ID == LW_FIRE) { if(Link->Item[I_CANDLE1]) radius = RAD_CANDLE1; if(Link->Item[I_CANDLE2]) radius = RAD_CANDLE2; //if this weapon has not been set up, set it up if(cur_weapon->Misc[0] == 0) { cur_weapon->Misc[0] = 1; cur_weapon->Misc[1] = FListGetFresh(flist, fdata); cur_weapon->Misc[2] = 0; lightsR[cur_weapon->Misc[1]] = radius; } //store various attributes of the weapon to start contracting if it vanishes cur_weapon->Misc[2] = Min(cur_weapon->Misc[2] + 1, LIGHT_EXPAND_TIME); lightsT[cur_weapon->Misc[1]] = Min(Floor(LIGHT_CONTRACT_TIME * (cur_weapon->Misc[2] / LIGHT_EXPAND_TIME)), LIGHT_CONTRACT_TIME); lightsX[cur_weapon->Misc[1]] = cur_weapon->X; lightsY[cur_weapon->Misc[1]] = cur_weapon->Y; idsFound[cur_weapon->Misc[1]] = true; if(radius > 0) { calcedRadius = radius * radius_var * (cur_weapon->Misc[2] / LIGHT_EXPAND_TIME); Screen->Circle(5, cur_weapon->X + 8, cur_weapon->Y + 8, calcedRadius, 0, 1, 0, 0, 0, true, 128); } } if(cur_weapon->ID == LW_BRANG) { radius = RAD_CANDLE1; if(curEquipmentB == I_CANDLE2) radius = RAD_CANDLE2; calcedRadius = radius * radius_var * (lightsLinkTimer / lightsLinkMaxTimer); Screen->Circle(5, cur_weapon->X + 8, cur_weapon->Y + 8, calcedRadius, 0, 1, 0, 0, 0, true, 128); } //reflected fireball if(cur_weapon->ID == LW_REFFIREBALL) { radius = 12; //if this weapon has not been set up, set it up if(cur_weapon->Misc[0] == 0) { cur_weapon->Misc[0] = 1; cur_weapon->Misc[1] = FListGetFresh(flist, fdata); cur_weapon->Misc[2] = LIGHT_CONTRACT_TIME; lightsR[cur_weapon->Misc[1]] = radius; } //store various attributes of the weapon to start contracting if it vanishes cur_weapon->Misc[2] = Min(cur_weapon->Misc[2] + 1, LIGHT_EXPAND_TIME); lightsT[cur_weapon->Misc[1]] = Min(Floor(LIGHT_CONTRACT_TIME * (cur_weapon->Misc[2] / LIGHT_EXPAND_TIME)), LIGHT_CONTRACT_TIME); lightsX[cur_weapon->Misc[1]] = cur_weapon->X; lightsY[cur_weapon->Misc[1]] = cur_weapon->Y; idsFound[cur_weapon->Misc[1]] = true; calcedRadius = radius * radius_var * (cur_weapon->Misc[2] / LIGHT_EXPAND_TIME); Screen->Circle(5, cur_weapon->X + 8, cur_weapon->Y + 6, calcedRadius, 0, 1, 0, 0, 0, true, 128); } } //eweapon fire eweapon ene_weapon; for(int i = 1; i <= Screen->NumEWeapons(); ++i) { ene_weapon = Screen->LoadEWeapon(i); radius = 0; float x_off = 0; float y_off = 0; if(ene_weapon->ID == EW_FIRE) { radius = 36; } else if(ene_weapon->ID == EW_FIRE2) { radius = 36; } else if(ene_weapon->ID == EW_FIREBALL) { radius = 12; y_off = -2; } else if(ene_weapon->ID == EW_FIREBALL2) { radius = 12; y_off = -2; } else if(ene_weapon->ID == EW_FIRETRAIL) { radius = 12; } else if(ene_weapon->ID == EW_SCRIPT1) { Screen->Circle(5, ene_weapon->X + 8, ene_weapon->Y + 8, 40 * radius_var, 0, 1, 0, 0, 0, true, 128); } else if(ene_weapon->ID == EW_SCRIPT2) { radius = 12; y_off = -2; } if(radius > 0) { //if this weapon has not been set up, set it up if(ene_weapon->Misc[0] == 0) { ene_weapon->Misc[0] = 1; ene_weapon->Misc[1] = FListGetFresh(flist, fdata); ene_weapon->Misc[2] = 0; lightsR[ene_weapon->Misc[1]] = radius; } //store various attributes of the weapon to start contracting if it vanishes ene_weapon->Misc[2] = Min(ene_weapon->Misc[2] + 1, LIGHT_EXPAND_TIME); lightsT[ene_weapon->Misc[1]] = Min(Floor(LIGHT_CONTRACT_TIME * (ene_weapon->Misc[2] / LIGHT_EXPAND_TIME)), LIGHT_CONTRACT_TIME); lightsX[ene_weapon->Misc[1]] = ene_weapon->X; lightsY[ene_weapon->Misc[1]] = ene_weapon->Y; idsFound[ene_weapon->Misc[1]] = true; calcedRadius = radius * radius_var * (ene_weapon->Misc[2] / LIGHT_EXPAND_TIME); Screen->Circle(5, ene_weapon->X + 8 + x_off, ene_weapon->Y + 8 + y_off, calcedRadius, 0, 1, 0, 0, 0, true, 128); } } //enemies npc cur_npc; for(int i = 1; i <= Screen->NumNPCs(); ++i) { cur_npc = Screen->LoadNPC(i); radius = 0; //fire zora if(cur_npc->ID == 181 && cur_npc->Tile >= 13120) { radius = 36; } else if(cur_npc->ID == 181 && cur_npc->Tile < 13120) { cur_npc->Misc[0] = 0; } //fire gel/zol else if(cur_npc->ID == NPC_GELFIRE) { radius = 12; } else if(cur_npc->ID == NPC_ZOLFIRE) { radius = 20; } //fire gibdo else if(cur_npc->ID == 183) { radius = 32; } if(radius > 0) { //if this weapon has not been set up, set it up if(cur_npc->Misc[0] == 0) { cur_npc->Misc[0] = 1; cur_npc->Misc[1] = FListGetFresh(flist, fdata); cur_npc->Misc[2] = 0; lightsR[cur_npc->Misc[1]] = radius; } //store various attributes of the weapon to start contracting if it vanishes cur_npc->Misc[2] = Min(cur_npc->Misc[2] + 1, LIGHT_EXPAND_TIME); lightsT[cur_npc->Misc[1]] = Min(Floor(LIGHT_CONTRACT_TIME * (cur_npc->Misc[2] / LIGHT_EXPAND_TIME)), LIGHT_CONTRACT_TIME); lightsX[cur_npc->Misc[1]] = cur_npc->X; lightsY[cur_npc->Misc[1]] = cur_npc->Y; idsFound[cur_npc->Misc[1]] = true; calcedRadius = radius * radius_var * (cur_npc->Misc[2] / LIGHT_EXPAND_TIME); Screen->Circle(5, cur_npc->X + 8, cur_npc->Y + 8, calcedRadius, 0, 1, 0, 0, 0, true, 128); } } } else { int x_off = 0; int y_off = 0; if(transition_dir == DIR_LEFT) x_off = -256 * (transition / 64); if(transition_dir == DIR_RIGHT) x_off = 256 * (transition / 64); if(transition_dir == DIR_UP) y_off = -176 * (transition / 44); if(transition_dir == DIR_DOWN) y_off = 176 * (transition / 44); //Link int radius = 0; float calcedRadius = 0.0; if(curEquipmentB == I_CANDLE1) { radius = RAD_CANDLE1; lightsLinkMaxTimer = LIGHT_EXPAND_TIME; } if(curEquipmentB == I_CANDLE2) { radius = RAD_CANDLE2; lightsLinkMaxTimer = Floor((RAD_CANDLE2 / RAD_CANDLE1) * LIGHT_EXPAND_TIME); } if(curEquipmentB == I_BRANG3) { radius = RAD_CANDLE1; lightsLinkMaxTimer = LIGHT_EXPAND_TIME; } if(radius > 0) { if(lightsLinkTimer < lightsLinkMaxTimer) lightsLinkTimer++; if(lightsLinkTimer > lightsLinkMaxTimer) lightsLinkTimer--; calcedRadius = radius * radius_var * (lightsLinkTimer / lightsLinkMaxTimer); Screen->Circle(5, Link->X + 8 + x_off, Link->Y + 8 + y_off, calcedRadius, 0, 1, 0, 0, 0, true, 128); } else { lightsLinkTimer = Max(lightsLinkTimer - 3, 0); //draw contracting circle if(lightsLinkTimer > 0) { if(Link->Item[I_CANDLE1]) { radius = RAD_CANDLE1; lightsLinkMaxTimer = LIGHT_EXPAND_TIME; } if(Link->Item[I_CANDLE2]) { radius = RAD_CANDLE2; lightsLinkMaxTimer = Floor((RAD_CANDLE2 / RAD_CANDLE1) * LIGHT_EXPAND_TIME); } calcedRadius = radius * radius_var * (lightsLinkTimer / lightsLinkMaxTimer); Screen->Circle(5, Link->X + 8, Link->Y + 8, calcedRadius, 0, 1, 0, 0, 0, true, 128); } } //Lights for(int i = 0; i < 176; i++) { if(Screen->ComboT[i] == CT_LIGHT) { Screen->Circle(5, ((i % 16) * 16) + 8 + x_off, (((i / 16) << 0) * 16) + 8 + y_off, RAD_TILE * radius_var, 0, 1, 0, 0, 0, true, 128); } } //Shutter if(Screen->Flags[SF_MISC] && 4 == 4) { Screen->Rectangle(5, 96 - 64*(1 - radius_var)/3 + x_off, 64 - 48*(1 - radius_var)/3 + y_off, 160 + 64*(1 - radius_var)/3 + x_off, 112 + 48*(1 - radius_var)/3 + y_off, 0, 1, 0, 0, 0, true, OP_OPAQUE); } //Other room lights //int screen = Game->GetCurScreen(); int screen = prev_screen; if(transition_dir == DIR_LEFT) { x_off += 256; } if(transition_dir == DIR_RIGHT) { x_off -= 256; } if(transition_dir == DIR_UP) { y_off += 176; } if(transition_dir == DIR_DOWN) { y_off -= 176; } for(int i = 0; i < 176; i++) { if(Game->GetComboType(Game->GetCurMap(), screen, i) == CT_LIGHT) { Screen->Circle(5, ((i % 16) * 16) + 8 + x_off, (((i / 16) << 0) * 16) + 8 + y_off, RAD_TILE * radius_var, 0, 1, 0, 0, 0, true, 128); } } //Other Shutter if(Game->GetScreenFlags(Game->GetCurMap(), screen, SF_MISC) && 4 == 4) { Screen->Rectangle(5, 96 - 64*(1 - radius_var)/3 + x_off, 64 - 48*(1 - radius_var)/3 + y_off, 160 + 64*(1 - radius_var)/3 + x_off, 112 + 48*(1 - radius_var)/3 + y_off, 0, 1, 0, 0, 0, true, OP_OPAQUE); } } //draw the contracting circles, and remove those that are finished contracting for(int i = 0; i < lightsCapacity; i++) { int x_off = 0; int y_off = 0; if(transition > 0) { if(transition_dir == DIR_LEFT) x_off = 256 - 256 * (transition / 64); if(transition_dir == DIR_RIGHT) x_off = -256 + 256 * (transition / 64); if(transition_dir == DIR_UP) y_off = 176 - 176 * (transition / 44); if(transition_dir == DIR_DOWN) y_off = -176 + 176 * (transition / 44); } if(!idsFound[i] && fdata[i]) { //draw contracting circle float calcedRadius = lightsR[i] * radius_var * (lightsT[i] / LIGHT_CONTRACT_TIME); Screen->Circle(5, lightsX[i] + 8 + x_off, lightsY[i] + 8 + y_off, calcedRadius, 0, 1, 0, 0, 0, true, 128); //countdown and remove if necessary lightsT[i] -= 1; if(lightsT[i] <= 0) { FListSetFree(flist, fdata, i); } } } //dragon super darkness if(dragon_dark()) { //get relevant shared variables dragon = Screen->LoadFFC(1); if(dragon->Misc[11] == 1) { cameraY = dragon->Misc[0]; darkness_x = dragon->Misc[3]; darkness_y = dragon->Misc[4]; darkness_t = dragon->Misc[5]; //dark circles for(int i = 0; i < 8; i++) { if(darkness_t[i] >= 400) { for(int c = 0; c < 3; c++){ float scale = (500 - darkness_t[i])/100; float angle = Randf(360); Screen->Circle(5, darkness_x[i] + scale* 8 * Cos(angle), darkness_y[i] + scale * 8 * Sin(angle) - cameraY, scale * 24, PURPLE + 1, 1, 0, 0, 0, true, OP_OPAQUE); } } else if(darkness_t[i] >= 0) { for(int c = 0; c < 3; c++){ float angle = Randf(360); Screen->Circle(5, darkness_x[i] + 8 * Cos(angle), darkness_y[i] + 8 * Sin(angle) - cameraY, 24, PURPLE + 1, 1, 0, 0, 0, true, OP_OPAQUE); } } } } } //Set the render target back to the screen. Screen->SetRenderTarget(RT_SCREEN); //Draw the bitmap we created. Screen->DrawBitmap(6, 1, 0, 0, 256, 176, 0, 0, 256, 176, 0, true); } else if(prevDark) { //clear appropriate dark room related variables for(int i = 0; i < lightsCapacity; i++) { lightsX[i] = 0; lightsY[i] = 0; lightsT[i] = 0; lightsR[i] = 0; FListClear(flist, fdata); } lightsLinkTimer = 0; //make the dark room layer opaque again for(int i = 0; i < 176; i++) { Game->SetComboData(DARK_MAP, DARK_SCREEN, i, CB_DARK); } prevDark = false; } //DARK ROOM END //UNDERWATER if(GetDMapFlag(Game->GetCurDMap(), DMF_UNDERWATER)) { Screen->Wavy = 2; } else if(!dragon_dark()) { Screen->Wavy = 0; } //UNERWATER END //YUKI TEXT //check if we should try choosing a new conversation if(next_conversation < 0 && !conversation_interupt()) { //decide the next conversation int num_convos = SizeOfArray(conversations); int best_index = -1; int best_order = 10000; for(int i = 0; i < num_convos; i++) { int cur_convo = conversations[i]; //check if the conversation is available if(convo_pre_cond(cur_convo) && !convo_post_cond(cur_convo)) { //check if it has not been played if(coversations_played[i] == 0) { //check if the order is better than the current best if(convo_order(cur_convo) < best_order) { best_index = i; best_order = convo_order(cur_convo); } } } } if(best_index > -1) { next_conversation = best_index; time_till_conversation = convo_wait_time(conversations[best_index]); } dialog_index = 0; text_length = 0; } //if there is a conversation playing, it can be interupted if(next_conversation >= 0 && !conversation_interupt()) { //if their is still time until the next conversation, wait and countdown if(time_till_conversation > 0) { //if the hurry condition is satisfied, countdown faster if(convo_hurry_cond(conversations[next_conversation])) { time_till_conversation = Max(0, time_till_conversation - 10); } //if the post conditions have been met, give up on this convo else if(convo_post_cond(conversations[next_conversation])) { next_conversation = -1; } else { time_till_conversation--; } } //otherwise, play the conversation else { int current_convo = conversations[next_conversation]; int current_speed = convo_text_speed(current_convo); int current_static = convo_static_denom(current_convo); int current_dialog = convo_dialog(current_convo); int current_string = current_dialog[dialog_index]; int current_text[256]; for(int i = 0; i < text_length; i++) { current_text[i] = current_string[i]; } current_text[text_length] = 0; //decide how to advance text if(frame % current_speed == 0) { //if the current string still needs to play if(text_length < SizeOfArray(current_string)) { text_length = Min(text_length + 1, SizeOfArray(current_string)); if(text_length < SizeOfArray(current_string)) { if(current_string[text_length-1] != ' ') { Game->PlaySound(SFX_MSG); } } } //otherwise wait for a bit else { if(string_end_wait < 7) { string_end_wait++; } //then move to the next string, or end the dialog else { string_end_wait = 0; text_length = 0; dialog_index++; if(dialog_index == SizeOfArray(current_dialog)) { dialog_index = 0; coversations_played[next_conversation] = 1; //for special goriya messages, if one has played, consider all played if(next_conversation == 18 || next_conversation == 19 || next_conversation == 20) { coversations_played[18] = 1; coversations_played[19] = 1; coversations_played[20] = 1; } next_conversation = -1; } } } } Screen->Rectangle( 7, 102, -15, 246, -5, 0x0E, 1, 0, 0, 0, true, OP_OPAQUE ); Screen->Rectangle( 7, 102, -15, 246, -5, 0x0F, 1, 0, 0, 0, false, OP_OPAQUE ); Screen->DrawString( 7, 104, -13, FONT_GBLA, 0x08, -1, TF_NORMAL, current_text, OP_OPAQUE ); //decide where the static should be every few frames if(frame % 16 == 0) { for(int x = 0; x < 140; x++) { for(int y = 0; y < 7; y++) { text_static[140 * y + x] = (Cond(Rand(1, current_static) == 1, 1, 0) == 1); } } } //draw the static over the text for(int x = 0; x < 140; x++) { for(int y = 0; y < 7; y++) { if(text_static[140 * y + x]) { Screen->PutPixel( 7, 104 + x, y - 13, 0x0E, 0, 0, 0, OP_OPAQUE ); } } } } } else { next_conversation = -1; time_till_conversation = 0; } //YUKI TEXT END //TESTS if(false){ condition_tester(); int convo_timer_string[10]; itoa(convo_timer_string, time_till_conversation); //int snow_string[10]; //itoa(snow_string, snow_intensity); //Screen->DrawString(7, 0, -48, FONT_Z3SMALL, 0x08, 0x01, TF_NORMAL, convo_timer_string, OP_OPAQUE); //Screen->DrawString(7, 0, -48, FONT_Z3SMALL, 0x08, 0x01, TF_NORMAL, snow_string, OP_OPAQUE); Screen->DrawString(7, 0, -56, FONT_GBLA, 0x04, 0x01, TF_NORMAL, password, OP_OPAQUE); } //TESTS //SHIELDS (pre-waitdraw) //if the shield is equipped to B, give the actual shield item, //otherwise, remove it if(curEquipmentB != prevEquipmentB) { Link->Item[I_SHIELD1] = (curEquipmentB == I_SMALL_SHIELD); Link->Item[I_SHIELD2] = (curEquipmentB == I_MAGIC_SHIELD); Link->Item[I_SHIELD3] = (curEquipmentB == I_MIRROR_SHIELD); } //Link begins strafing by pressing B, but he can only begin strafing //during certain actions, and when a shield is equipped to B if(Link->InputB && (Link->Action == LA_NONE || Link->Action == LA_WALKING || Link->Action == LA_GOTHURTLAND) && (curEquipmentB == I_SMALL_SHIELD || curEquipmentB == I_MAGIC_SHIELD || curEquipmentB == I_MIRROR_SHIELD)) { if(strafing == 0) { strafing = 1; strafe_dir = Link->Dir; //shield sound //Game->PlaySound(66); } } //in any other case, stop strafing else { strafing = 0; } //while Link is strafing, he cannot use the sword if(strafing == 1) { Link->InputA = false; Link->PressA = false; } //SHIELDS (more after waitdraw) //STUPID BOMB BAG THING if(!Link->Item[I_BOMBBAG1] && Link->Item[I_BOMB]) Link->Item[I_BOMB] = false; //STUPID BOMB BAG THING //JINX EFFECTS if(Link->SwordJinx != 0 && !Link->Invisible) { //draw a curse effect int x_off = 0; int y_off = 0; if(transition_dir == DIR_LEFT) x_off = -256 * (transition / 64); if(transition_dir == DIR_RIGHT) x_off = 256 * (transition / 64); if(transition_dir == DIR_UP) y_off = -176 * (transition / 44); if(transition_dir == DIR_DOWN) y_off = 176 * (transition / 44); Screen->DrawTile(3, Link->X + x_off, Link->Y - 14 + y_off, TL_JINX + (Div(frame, 8) % 4), 1, 2, 8, -1, -1, 0, 0, 0, 0, true, OP_TRANS); } //JINX EFFECTS END //BOOMERANG if(frame % 4 == 0) { for(int i = 4; i > 0; i--) { boomerflamesX[i] = boomerflamesX[i-1]; boomerflamesY[i] = boomerflamesY[i-1]; } if(brangInFlight) { boomerflamesX[0] = brang->X + Rand(-6,7); boomerflamesY[0] = brang->Y + Rand(-10,4); } else if(curEquipmentB == I_BRANG3) { int x_off = 0; int y_off = 0; if(transition > 16) { if(transition_dir == DIR_LEFT) x_off = -256; if(transition_dir == DIR_RIGHT) x_off = 256; if(transition_dir == DIR_UP) y_off = -176; if(transition_dir == DIR_DOWN) y_off = 176; } boomerflamesX[0] = Link->X + Rand(-6,7) + x_off; boomerflamesY[0] = Link->Y + Rand(-10,4) + y_off - Link->Z; } else { boomerflamesX[0] = -1; boomerflamesY[0] = -1; } } //flame draw for(int i = 0; i < 5; i++) { int x_off = 0; int y_off = 0; if(transition > 0) { if(transition_dir == DIR_LEFT) x_off = 256 - 256 * (transition / 64); if(transition_dir == DIR_RIGHT) x_off = -256 + 256 * (transition / 64); if(transition_dir == DIR_UP) y_off = 176 - 176 * (transition / 44); if(transition_dir == DIR_DOWN) y_off = -176 + 176 * (transition / 44); } if(boomerflamesX[i] != -1) { Screen->FastTile(3, boomerflamesX[i] + x_off, boomerflamesY[i] + y_off, FLAME_BASE + i, 8, OP_OPAQUE); } } //BOOMERANG END //WARP PUZZLE if(Game->GetDMapScreenD(25, 0x20, 2) > 0) { if(Game->GetDMapScreenD(25, 0x20, 2) == 1) { Game->PlaySound(SFX_SECRET); Game->SetScreenState(10, 0x2A, ST_SECRET, true); } Game->SetDMapScreenD(25, 0x20, 2, Game->GetDMapScreenD(25, 0x20, 2) - 1); } if(Game->GetDMapScreenD(24, 0x02, 1) > 0 && Game->GetDMapScreenD(24, 0x02, 2) > 0) { if(Game->GetDMapScreenD(24, 0x02, 1) <= 4 && Game->GetDMapScreenD(24, 0x02, 2) <= 4 && ( (Game->GetDMapScreenD(26, 0x31, 1) == DIR_LEFT && Game->GetDMapScreenD(26, 0x31, 2) == DIR_RIGHT) || (Game->GetDMapScreenD(26, 0x31, 1) == DIR_DOWN && Game->GetDMapScreenD(26, 0x31, 2) == DIR_UP) ) ) { Game->PlaySound(SFX_SECRET); Game->SetScreenState(10, 0x3B, ST_SECRET, true); Game->SetDMapScreenD(24, 0x02, 1, 0); Game->SetDMapScreenD(24, 0x02, 2, 0); } } if(Game->GetDMapScreenD(24, 0x02, 1) > 0) { Game->SetDMapScreenD(24, 0x02, 1, Max(0, Game->GetDMapScreenD(24, 0x02, 1) - 3)); } if(Game->GetDMapScreenD(24, 0x02, 2) > 0) { Game->SetDMapScreenD(24, 0x02, 2, Max(0, Game->GetDMapScreenD(24, 0x02, 1) - 3)); } //WARP PUZZLE END prevEquipmentB = curEquipmentB; Waitdraw(); //RESET BOOMER FLAMES //this is here so that prev_dmap is accurate if(Game->GetCurDMap() != prev_dmap) { for(int i = 0; i < 5; i++) { boomerflamesX[i] = -1; boomerflamesY[i] = -1; } } //RESET BOOMER FLAMES END //SHIELDS (post waitdraw) //Upon any kind of screen transition, cancel a strafe if(Game->GetCurScreen() != prev_screen || Game->GetCurDMap() != prev_dmap) { strafing = 0; } //Set Link's direction to be the same direction as it was at the start of the strafe //Note this must be after the Waitdraw or else the ZC engine will just set Link's //direction back to the direction he is actually moving if(strafing == 1) { //since ZScript is bad, assigning to Link->Dir also sets Link->Action (to walking?) behind the scenes //however, we still want Link's action to be able have other values, //so we reset Link->Action after changing his Dir int action = Link->Action; Link->Dir = strafe_dir; Link->Action = action; } //SHIELDS (more before waitdraw) //HOVER SLIPPERS if(Link->Item[I_HOVER_SLIPPERS]) { //make holes unsolid //note that map 0, screen 0 actually contains 5 hole combos //and this changes their solidity to be completely walkable for(int i = 0; i < 5; i++) { Game->SetComboSolid(0, 0, i, 0); } //if Link is on a hole, draw a hover shadow //check if on a hole bool on_hole = false; if(Screen->ComboT[ComboAt(Link->X, Link->Y + 8)] == CT_LADDERHOOKSHOT) on_hole = true; if(Screen->ComboT[ComboAt(Link->X, Link->Y + 15)] == CT_LADDERHOOKSHOT) on_hole = true; if(Screen->ComboT[ComboAt(Link->X + 15, Link->Y + 8)] == CT_LADDERHOOKSHOT) on_hole = true; if(Screen->ComboT[ComboAt(Link->X + 15, Link->Y + 15)] == CT_LADDERHOOKSHOT) on_hole = true; //draw the shadow if(on_hole) { Screen->FastTile(1, Link->X, Link->Y + 2, TL_SHADOW, 0, OP_TRANS ); } } //HOVER SLIPPERS END //DRAGON dragon_waitdraw(boomerflamesY); //DRAGON END Waitframe(); frame = (frame + 1) % 7200; } } } //Put this FFC on a screen that could have fire trails so that the sword will put them out ffc script SlashOutFlames { void run() { while(1) { //find a flame? for(int i = 1; i <= Screen->NumEWeapons(); i++) { eweapon flame = Screen->LoadEWeapon(i); if(flame->ID == EW_FIRETRAIL) { //find link's sword? for(int j = 1; j <= Screen->NumLWeapons(); j++) { lweapon sword = Screen->LoadLWeapon(j); if(sword->ID == LW_SWORD) { if(Collision(flame, sword)) { //remove the flame flame->DeadState = WDS_DEAD; } } } } } Waitframe(); } } } //super band-aidy fix to the dark room issue between the two screens in the first cave ffc script FireCircleCooldown { void run(int dmap, int screen) { int t = 0; while(t++ < 60) { NoActionPlus(); Waitframe(); } Link->PitWarp(dmap, screen); } } //plays a string and warps you to the town ffc script Intro { void run() { NoActionPlus(); Screen->Message(61); Waitframe(); for(int i = 0; i < 176; i++) { Screen->ComboD[i]++; } } } //make push block puzzles solved permanently without trigger hack //put this on a screen with temporary secrets if you want them to be permanent instead //monitor should be the pos of a combo that will change due to the secret ffc script PermBlockPuzzles { void run(int monitor) { int orig = Screen->ComboD[monitor]; while(1) { if(Screen->ComboD[monitor] != orig) { Screen->State[ST_SECRET] = true; break; } Waitframe(); } } } //Link will spawn a bit in the air and fall. Map is disabled. ffc script Falling { void run() { Link->Z = 120; Link->Dir = DIR_DOWN; while(1) { if(Link->Z == 119) { Game->PlaySound(SFX_FALL); } //Link->InputStart = false; Link->PressStart = false; Link->InputMap = false; Link->PressMap = false; NoActionPlus(); if(Link->Z <= 1) { for(int i = 0; i < 12; i++) { int px = i % 4; int py = Div(i, 4); int loc = 70 + px + 16*py; Screen->ComboD[loc]++; } } Waitframe(); } } }