// Halloween 2011 // Authors: alastrim, enchilado, o11c // This is a function that implements the whole quest (or at least stage 1) // Note: this function doesn't usually return // In the appropriate NPCs, do something like: //+ set @hw2011_npc_id, $@hw2011_npc_vincent; //+ if (gettime(7) == $@hw2011_year && gettime(6) == 10 && gettime(5) >= $@hw2011_start_day) //+ callfunc "TrickOrTreat2011"; // Variables: // $@hw2011_maskmemory = Sliced Array containing the record of the last masks used to trick or treat each NPC. // @hw2011_npc_id = NPC id, this variable is set when calling this function by an NPC // hw2011 = Permanent variable used to control your progress in the quest. // The high bits are used to keep track of the NPCs you already tricked while showing your face. // The low bits are used to keep track of how many times you've gotten treats. // Currently, the vague plan is 16 for each, but we may need to use this variable for the second part of the quest. function|script|TrickOrTreat2011|{ if ((gettimetick(2)-TUT_var < 7*86400) || (BaseLevel < $@hw2011_min_level)) //player must be created at least 1 weeks ago goto L_QuickReturn; menu "Trick or Treat", -, "[Go to normal NPC dialog]", L_QuickReturn; set @mask, getequipid(equip_head); if (@mask == 647) menu "Reset my quest state", L_ResetMe, "Reset this NPC's mask memory", L_ResetMask, "Just do the quest", -; L_Begin: set @karma, hw2011 & 0xffff; // must be early to handle all the one-off mes;s in the init stuff mes $@hw2011_npc_names$[@hw2011_npc_id]; if (@mask == -1) goto L_NoMask; // set the scare factor of the equipped mask set @mask_index, 0; set @scare_factor, 1; L_MaskLoop: if ($@hw2011_mask_IDs[@mask_index] == @mask) goto L_FoundMask; set @mask_index, @mask_index + 1; if ($@hw2011_mask_IDs[@mask_index]) goto L_MaskLoop; // not a mask in the list set @mask, 0; goto L_MaskDone; L_FoundMask: set @scare_factor, $@hw2011_scare_factors[@mask_index]; if (@mask != 616) goto L_MaskDone; mes "\"Aaargh... Gross! This is sick! I can't even look at your face...\""; // I would have done this instead of having the dialog explain //set @mask, 0; L_MaskDone: set @mask_index, 0; // check if the mask is in the memory set @loop, 0; // Note: we don't handle remembered faces until they get their candy if (!@mask) goto L_MaskMemoryNo; // check if the mask is remembered L_MaskMemoryCheck: set @tmp, $@hw2011_maskmemory[8 * @hw2011_npc_id + @loop]; if (!@tmp) goto L_MaskMemoryNo; if (@tmp == @mask) goto L_MaskMemoryYes; set @loop, @loop + 1; if (@loop != $@hw2011_memory_count) goto L_MaskMemoryCheck; goto L_MaskMemoryNo; L_MaskMemoryYes: // not necessarily true mes "\"I remember you, " + getequipname(equip_head) + " person. No more treats for you!\""; goto L_Close; L_MaskMemoryNo: // player will probably get treats set @loop, 0; set @sweets_types, 0; L_Count_Sweets: if ($@hw2011_sweets$[@loop] == "") goto L_Check_Inventory; if (countitem($@hw2011_sweets$[@loop])) set @sweets_types, @sweets_types + 1; set @loop, @loop + 1; goto L_Count_Sweets; L_Check_Inventory: getinventorylist; if (@inventorylist_count + (@loop - @hw2011_invy) > 100) goto L_Full_Inventory; if (@mask) goto L_Check_Karma; // check if the player's face is remembered if (hw2011 & (0x1 << (31 - @hw2011_npc_id))) goto L_Remember_Face; goto L_Tricking_Trick_or_Treat; L_Check_Karma: // Please don't change this, you'll break stuff. if (rand($@hw2011_num_npcs, 0xffff) <= @karma) goto L_Cheater; // this is a cheap, limited form of ilog2 if ((@karma >= 0x10) && !(rand( 4 - (@karma >= 0x40) + (@karma >= 0x100) + (@karma >= 0x400) ))) goto L_Cheater; if (hw2011 & $@hw2011_got_big_reward) goto L_Tricking_Trick_or_Treat; // assert: @karma < $@hw2011_num_npcs if (rand($@hw2011_num_npcs - @karma)) goto L_Tricking_Trick_or_Treat; mes "\"All this candy isn't healthy, here take this to have a break from it.\""; getitem $@hw2011_big_reward$, 1; set hw2011, hw2011 | $@hw2011_got_big_reward; // you get the big reward first, then the main treats // otherwise it would be too complicated, and/or possibly unfair goto L_Tricking_Trick_or_Treat; L_Cheater: mes "\"I recognize you despite your mask, you have been taking sweets you do not deserve.\""; if (@karma != 0xFFFF) set hw2011, hw2011 + 1; goto L_Close; L_Remember_Face: // mes "You've been here before; I remember your face"; mes "\"I remember your face, " + strcharinfo(0) + ". No more treats for you!\""; goto L_Close; L_Tricking_Trick_or_Treat: // moved above // mes $@hw2011_npc_names$[@hw2011_npc_id]; mes $@hw2011_greetings$[@hw2011_npc_id]; next; // TODO: should we randomize these? (in a subsequent commit) menu $@hw2011_trick_notscary$[@hw2011_npc_id], L_Tricking_Notscary, $@hw2011_trick_scary$[@hw2011_npc_id], L_Tricking_Scary, $@hw2011_trick_veryscary$[@hw2011_npc_id], L_Tricking_Veryscary; L_Tricking_Notscary: mes $@hw2011_npc_names$[@hw2011_npc_id]; mes $@hw2011_react_notscary$[@hw2011_npc_id]; goto L_Tricking_Reward; L_Tricking_Scary: mes $@hw2011_npc_names$[@hw2011_npc_id]; mes $@hw2011_react_scary$[@hw2011_npc_id]; set @scare_factor, @scare_factor * 2; goto L_Tricking_Reward; L_Tricking_Veryscary: mes $@hw2011_npc_names$[@hw2011_npc_id]; mes $@hw2011_react_veryscary$[@hw2011_npc_id]; set @scare_factor, @scare_factor * 3; goto L_Tricking_Reward; L_Tricking_Reward: next; if (@karma >= 0x10) set @scare_factor, rand(@scare_factor / 2, @scare_factor); if (@karma >= 0x100) set @scare_factor, rand(@scare_factor / 2, @scare_factor); if (@karma >= 0x1000) set @scare_factor, rand(@scare_factor / 2, @scare_factor); if (@scare_factor < 1) set @scare_factor, 1; L_Tricking_Reward_Loop: if (!@scare_factor) goto L_Tricking_End; // NOTE: it gives out one piece at a time, but can loop several times getitem $@hw2011_sweets$[rand($@hw2011_sweets_num)], 1; set @scare_factor, @scare_factor - 1; goto L_Tricking_Reward_Loop; L_SetRememberFace: set hw2011, hw2011 | (0x1 << (31 - @hw2011_npc_id)); goto L_Close; L_Tricking_End: mes $@hw2011_npc_names$[@hw2011_npc_id]; mes "\"That should be enough sweets for you. Thanks for participating!\""; if (!@mask) goto L_SetRememberFace; // add the player's mask to the list set @loop, 7; L_SetRememberMask: set $@hw2011_maskmemory[8 * @hw2011_npc_id + @loop], $@hw2011_maskmemory[8 * @hw2011_npc_id + @loop - 1]; set @loop, @loop - 1; if (@loop) goto L_SetRememberMask; set $@hw2011_maskmemory[8 * @hw2011_npc_id], @mask; set hw2011, hw2011 + 1; goto L_Close; L_Full_Inventory: mes $@hw2011_npc_names$[@hw2011_npc_id]; mes "\"You are trying to collect candy but you have no space to carry all the kinds of stuff that I have to offer! Please, save room for more stuff and come back.\""; goto L_Close; L_ScaryFace: mes "\"Eeeeeeeeeeeeeeeeeeeeeeeeeeekkkkkkkkkkkkkkkkk!!!\""; mes "\"Oh, that's your face ...\""; next; set @mask, 0; set @scarefactor, 2 + rand(3); goto L_MaskDone; L_NoMask: // TODO: are there any other players to make fun of? if (getcharid(3) == 2160466 || getcharid(3) == 2177906 || getcharid(3) == 2157647) goto L_ScaryFace; mes $@hw2011_npc_names$[@hw2011_npc_id]; mes "\"Hey " + strcharinfo(0) + ", are you trying to scare me with your face? Interesting! hahaha...\""; goto L_Close; L_Close: set @tmp, 0; set @mask, 0; set @karma, 0; set @loop, 0; set @menu, 0; set @hw2011_npc_id, 0; close; L_QuickReturn: set @hw2011_npc_id, 0; return; L_ResetMe: set hw2011, 0; goto L_Close; L_ResetMask: // the rest will be implicitly cleared set $@hw2011_maskmemory[8 * @hw2011_npc_id], 0; goto L_Close; }