Another script that I was hesitant to share due to how evil it is, this is partly tested, and the basic modes are known working. If anyone wishes to play with it while we test the rest of it, before I add it to the database, here is your chance.
This allows you to either manually place, or randomly spawn npcs from Slash->Next style combos, or create Z3 landmines from bushes or tall grass combos. Anyone who has played Z3 hacks is well-aware of how much shock value this type of thing can have.
I plan to use it to make enemies spring out of treasure chests, and such.
///////////////////////////////////////// /// Slash->Next Jack-In-The-Jox Enemy /// /// and Slash->Next Z3 Landmines /// /// 12-Nov-2016 - v0.5.3 /// /// By: ZoriaRPG /// ///////////////////////////////////////// /// Testers: /// /// JudasRising - Initial Debug Tests /// ///////////////////////////////////////// //Bush Enemy const int I_ENEMY_SPAWN = 200; //Add this to your dropsets to allow random npc spawns from slash combos. const int NPC_GUARD_BLUE = 49; const int NPC_GUARD_GREEN = 79; const int NPC_GUARD_RED = 50; //This array holds the enemy IDs for enemies that can be spawned by item 'I_ENEMY_SPAWN'. int ItemDropSpawnsEnemies[]={NPC_MOBLIN1, NPC_GUARD_RED, NPC_ROPE1, NPC_MOBLIN1, NPC_MOBLIN1, NPC_ZOL, NPC_STALFOS1, NPC_ROPE1, NPC_STALFOS1, NPC_GUARD_BLUE, NPC_GUARD_RED, NPC_GUARD_RED, NPC_GUARD_BLUE, NPC_ROPE2, NPC_GUARD_BLUE, NPC_GUARD_BLUE, NPC_GUARD_BLUE, NPC_GUARD_BLUE, NPC_GUARD_GREEN, NPC_GUARD_RED, NPC_DODONGO, NPC_ROPE1}; //Bush Landmine const int I_LANDMINE = 201; //Add this to your dropsets to allow random landmines from slash combos. const int MISC_LANDMINE_TIMER = 1; //The index of item->Misc[] to use for the timer. const int LANDMINE_TIMER_DELAY = -40; //The initial value of the timer. const int LANDMINE_TIMER_DELAY_TOUCHED = -10; //A value to jump to, if the timer is less than this, and the landmine is touched. const int LANDMINE_TIMER_EXPLODE = -1; //We explode at this value. const int LANDMINE_USE_BOMB_NOT_BOMBLAST = 0; //If set, a lit bomb will appear instead of a bombblast. //Setting the following disables both the bombblast, and the lit boms, and allows setting up a custom weapon. const int LANDMINE_SPARKLE_SPRITE = 0; //If set, the explosion will use an different sprite and a type specified below: //Set up a custom weapon, with hitbox sizing. const int LANDMINE_ALT_DAMAGE_EFFECT_TYPE = 140; //EW_FIRE const int LANDMINE_ALT_DAMAGE_EFFECT_HITX = 24; //EW_* Hitbox X Size const int LANDMINE_ALT_DAMAGE_EFFECT_HITXOFFSET = -8; //EW_* Hitbox X Offset const int LANDMINE_ALT_DAMAGE_EFFECT_HITY = 24; //EW_* Hitbox Y Size const int LANDMINE_ALT_DAMAGE_EFFECT_HITYOFFSET = -8; //EW_* Hitbox Y Offset //Settings const int USE_SCREEN_FLAG_TO_PERMIT_LANDMINES = 0; const int USE_SCREEN_FLAG_TO_PERMIT_SHASH_NEXT_NPCS = 0; const int USE_SCREEN_FLAG_TO_FORBID_LANDMINES = 0; const int USE_SCREEN_FLAG_TO_FORBID_SHASH_NEXT_NPCS = 0; //See std_constants.zh for a list of these flags. //Flag category const int SF_LANDMINES = 9; //SF_MISC const int SF_SLASHNEXTNPC = 9; //Flag in the category const int SF_LANDMINE_SET = 2; //Misc_1 const int SF_SLASHNEXTNPC_SET = 3; //Misc_2 //if ( USE_SCREEN_FLAG_TO_PERMIT_LANDMINES && (Screen->Flags[SF_LANDMINES]&SF_LANDMINE_SET != 0) ) //if ( USE_SCREEN_FLAG_TO_PERMIT_SHASH_NEXT_NPCS && ( Screen->Flags[SF_SLASHNEXTNPC]&SF_SLASHNEXTNPC_SET != 0 ) ) //if ( USE_SCREEN_FLAG_TO_FORBID_LANDMINES && (Screen->Flags[SF_LANDMINES]&SF_LANDMINE_SET == 0) ) //if ( USE_SCREEN_FLAG_TO_FORBID_SHASH_NEXT_NPCS && ( Screen->Flags[SF_SLASHNEXTNPC]&SF_SLASHNEXTNPC_SET == 0 ) ) //! Formula for statements that mesh with these options: //if ( ( !USE_SCREEN_FLAG_TO_FORBID_SHASH_NEXT_NPCS && !USE_SCREEN_FLAG_TO_PERMIT_SHASH_NEXT_NPCS ) || // ( ( USE_SCREEN_FLAG_TO_PERMIT_SHASH_NEXT_NPCS && (Screen->Flags[SF_SLASHNEXTNPC]&SF_SLASHNEXTNPC_SET != 0) ) || // ( USE_SCREEN_FLAG_TO_FORBID_SHASH_NEXT_NPCS && (Screen->Flags[SF_SLASHNEXTNPC]&SF_SLASHNEXTNPC_SET == 0) ) ) ) // //if ( ( !USE_SCREEN_FLAG_TO_FORBID_LANDMINES && !USE_SCREEN_FLAG_TO_PERMIT_LANDMINES ) || // ( ( USE_SCREEN_FLAG_TO_PERMIT_LANDMINES && (Screen->Flags[SF_LANDMINES]&SF_LANDMINE_SET != 0) ) || // ( USE_SCREEN_FLAG_TO_FORBID_LANDMINES && (Screen->Flags[SF_LANDMINES]&SF_LANDMINE_SET == 0) ) ) ) //Use a specific combo as part of slash->Next instead of a dropset item. const int AUTO_LANDMINES_USE_COMBO_NOT_ITEM = 0; const int AUTO_JACKINTHEBOX_USE_COMBO_NOT_ITEM = 0; const int SHOW_LANDMINE_TIMER = 1; //This only works if using an item for the landmine. const int FLASH_LANDMIN_TIMER_DISPLAY = 1; const int LANDMINE_TIMER_FONT = 16; //LA const int LANDMINE_FONT_BG_COLOUR = 0x0F; const int LANDMINE_FONT_FG_COLOUR = 0x01; const int LANDMINE_FONT_FG_COLOUR_FLASH = 0x03; const int LANDMINE_FONT_FG_X_OFFSET = 17; const int LANDMINE_FONT_FG_Y_OFFSET = 18; const int LANDMINE_FONT_BG_X_OFFSET = 16; const int LANDMINE_FONT_BG_Y_OFFSET = 17; const int LANDMINE_FONT_WIDTH = 4; const int LANDMINE_FONT_HEIGHT = 4; const int LANDMINE_FONT_OPACITY = 128; const int LANDMINE_FONT_LAYER = 1; const int LANDMINE_TIMER_DISPLAY_DIVISOR = 10; const int LANDMINE_TIMER_FLASH_TIMING = 4; void ItemSpawnsEnemyOrLandmine(){ for ( int q = Screen->NumItems(); q > 0; q-- ) { item i = Screen->LoadItem(q); eweapon ew; lweapon l; bool proceed; if ( i->ID == I_ENEMY_SPAWN ) { i->Pickup = IP_DUMMY; if ( !USE_SCREEN_FLAG_TO_FORBID_SHASH_NEXT_NPCS && !USE_SCREEN_FLAG_TO_PERMIT_SHASH_NEXT_NPCS ) proceed = true; if ( USE_SCREEN_FLAG_TO_PERMIT_SHASH_NEXT_NPCS && ScreenFlag(SF_SLASHNEXTNPC,SF_SLASHNEXTNPC_SET) ) proceed = true; if ( USE_SCREEN_FLAG_TO_FORBID_SHASH_NEXT_NPCS && !ScreenFlag(SF_SLASHNEXTNPC,SF_SLASHNEXTNPC_SET) ) proceed = true; if ( proceed ) { npc n = Screen->CreateNPC( ItemDropSpawnsEnemies[Rand(SizeOfArray(ItemDropSpawnsEnemies))] ); n->X = i->X; n->Y = i->Y; Remove(i); } else Remove(i); } if ( i->ID == I_LANDMINE ) { i->Pickup = IP_DUMMY; if ( !USE_SCREEN_FLAG_TO_FORBID_LANDMINES && !USE_SCREEN_FLAG_TO_PERMIT_LANDMINES ) proceed = true; if ( USE_SCREEN_FLAG_TO_PERMIT_LANDMINES && ScreenFlag(SF_LANDMINES,SF_LANDMINE_SET) ) proceed = true; if ( USE_SCREEN_FLAG_TO_FORBID_LANDMINES && !ScreenFlag(SF_LANDMINES,SF_LANDMINE_SET) ) proceed = true; if ( proceed ) { if ( SHOW_LANDMINE_TIMER && i->Misc[MISC_LANDMINE_TIMER] < 0 ) { Screen->DrawInteger( LANDMINE_FONT_LAYER, i->X + LANDMINE_FONT_BG_X_OFFSET, i->Y + LANDMINE_FONT_BG_Y_OFFSET, LANDMINE_TIMER_FONT, LANDMINE_FONT_BG_COLOUR, 0, LANDMINE_FONT_WIDTH, LANDMINE_FONT_HEIGHT, ( ( LANDMINE_TIMER_DELAY * -1 ) - ( i->Misc[MISC_LANDMINE_TIMER] * -1 ) ) / LANDMINE_TIMER_DISPLAY_DIVISOR, 0, LANDMINE_FONT_OPACITY); if ( !FLASH_LANDMIN_TIMER_DISPLAY || FLASH_LANDMIN_TIMER_DISPLAY && ( i->Misc[MISC_LANDMINE_TIMER] * -1 ) % LANDMINE_TIMER_FLASH_TIMING != 0 ) Screen->DrawInteger( LANDMINE_FONT_LAYER, i->X + LANDMINE_FONT_FG_X_OFFSET, i->Y + LANDMINE_FONT_FG_Y_OFFSET, LANDMINE_TIMER_FONT, LANDMINE_FONT_FG_COLOUR, 0, LANDMINE_FONT_WIDTH, LANDMINE_FONT_HEIGHT, ( ( LANDMINE_TIMER_DELAY * -1 ) - ( i->Misc[MISC_LANDMINE_TIMER] * -1 ) ) / LANDMINE_TIMER_DISPLAY_DIVISOR, 0, LANDMINE_FONT_OPACITY); else Screen->DrawInteger( LANDMINE_FONT_LAYER, i->X + LANDMINE_FONT_FG_X_OFFSET, i->Y + LANDMINE_FONT_FG_Y_OFFSET, LANDMINE_TIMER_FONT, LANDMINE_FONT_FG_COLOUR_FLASH, 0, LANDMINE_FONT_WIDTH, LANDMINE_FONT_HEIGHT, ( ( LANDMINE_TIMER_DELAY * -1 ) - ( i->Misc[MISC_LANDMINE_TIMER] * -1 ) ) / LANDMINE_TIMER_DISPLAY_DIVISOR, 0, LANDMINE_FONT_OPACITY); } if ( !i->Misc[MISC_LANDMINE_TIMER] ) { i->Misc[MISC_LANDMINE_TIMER] = LANDMINE_TIMER_DELAY; } if ( i->Misc[MISC_LANDMINE_TIMER] ) { if ( i->Misc[MISC_LANDMINE_TIMER] == LANDMINE_TIMER_EXPLODE ) { if ( LANDMINE_SPARKLE_SPRITE ) { l = Screen->CreateLWeapon(LW_SPARKLE); l->UseSprite(LANDMINE_SPARKLE_SPRITE); l->HitXOffset = -200; l->X = i->X; l->Y = i->Y; ew = Screen->CreateEWeapon(LANDMINE_ALT_DAMAGE_EFFECT_TYPE); ew->X = i->X + LANDMINE_ALT_DAMAGE_EFFECT_HITX; ew->Y = i->Y + LANDMINE_ALT_DAMAGE_EFFECT_HITY; ew->HitXOffset = LANDMINE_ALT_DAMAGE_EFFECT_HITXOFFSET; ew->HitYOffset = LANDMINE_ALT_DAMAGE_EFFECT_HITYOFFSET; } else { if ( LANDMINE_USE_BOMB_NOT_BOMBLAST ) ew = Screen->CreateEWeapon(EW_BOMBBLAST); //this is wrong else ew = Screen->CreateEWeapon(EW_BOMBBLAST); ew->X = i->X; ew->Y = i->Y; } Remove(i); } if ( i->Misc[MISC_LANDMINE_TIMER] < LANDMINE_TIMER_DELAY_TOUCHED && LinkCollision(i) ) { //I would prefer collision only with the lower part of Link for this, as a step trigger. // ew = Screen->CreateEWeapon(EW_BOMBBLAST); //ew->X = i->X; ew->Y = i->Y; //Remove(i); i->Misc[MISC_LANDMINE_TIMER] = LANDMINE_TIMER_DELAY_TOUCHED; //Advance the delay when touched. } else i->Misc[MISC_LANDMINE_TIMER]++; } } else Remove(i); } } } void ItemSpawnsEnemy(){ for ( int q = Screen->NumItems(); q > 0; q-- ) { item i = Screen->LoadItem(q); if ( i->ID == I_ENEMY_SPAWN ) { i->HitXOffset = -200; npc n = Screen->CreateNPC( ItemDropSpawnsEnemies[Rand(SizeOfArray(ItemDropSpawnsEnemies))] ); n->X = i->X; n->Y = i->Y; } } } //! Example Global Script global script BushSurpriseDemo{ void run(){ while(true){ ItemSpawnsEnemyOrLandmine(); Waitdraw(); Waitframe(); } } } //! FFC to manually place lndmines, or enemies. //!!! This ffc works in conjunction with the global script. You must use the global script to generate //!!! npcs and explosions. //! If you wish to manually place NPCs or Landmines to appear out of pots, or bushes, or if you do not //! want to allow these things to appear under any slash combo, use this ffc to generate them. //! Using this, you do not need to add I_LANDMINE or I_ENEMY_SPAWN to shash combo droplists, although //! you may still add either, or both, if you wish. //Set D0 as follows: -1 for random NPC from list, 0 for landmine, positive number for a specific npc (use the npc ID). //Set D1 to the second combo of a Slash->Next pair. If a pot combo is ID 120, then this value should be 121 (broken pot). //Set D2 if you use a specific npc, to set a delay before spawning it, or to add a delay into other effects. ffc script PlaceSLashNextNPC_or_Landmine{ void run(int npc_id, int comboID, int delay){ npc n; item i; while(true){ if ( Screen->ComboD[ComboAt(this->X, this->Y)] == comboID ) { if ( npc_id > 0 ) { Waitframes(delay); n = Screen->CreateNPC(npc_id); n->X = this->X; n->Y = this->Y; Waitframe(); this->Data = 0; this->Script = 0; Quit(); } if ( npc_id < 0 ) { Waitframes(delay); i = Screen->CreateItem(I_ENEMY_SPAWN); i->Pickup = IP_DUMMY; i->X = this->X; i->Y = this->Y; Waitframe(); this->Data = 0; this->Script = 0; Quit(); } if ( !npc_id ) { Waitframes(delay); i = Screen->CreateItem(I_LANDMINE); i->Pickup = IP_DUMMY; i->X = this->X; i->Y = this->Y; Waitframe(); this->Data = 0; this->Script = 0; Quit(); } } Waitframe(); } } }
As you can see, there are a variety of config options, depending on how you want the landmines to work. Similarly, you can make enemies randomly appear from Slash->Item combos, or you may manually place an ffc over any combo->Next type, or over a secret combo so that it activates when the combo changes.
Perhaps you want a Step->Secrets trigger that spawns five Darknuts? If so, this is your drug of choice to do exactly that!
Once we fully test it, I'll upload it to the database, along with example quests. Detailed set-up instructions shall follow, when the example quests are ready. In the interim, enjoy!
Special thanks to JudasRising for deep testing, debugging collab, and demo quest generation.
Edited by ZoriaRPG, 12 November 2016 - 12:45 PM.