Item Description:
The Phantom Cloak is an item that allows you to dash forward several tiles (possibly through special blocks that would normally be solid, defaulting to the script 2 combo flag), dealing damage along the way. You also leave a bait at your original location, drawn transparently.
To setup, you need to examine everything the Integration section of code to make sure that it's compatible with your quest. The following two sections, Behavior and Default Arguments, have isolated some of the easier parts of the script to modify.
Then, give an item the activation script Use_PhantomCloak. The arguments are in the same order and effect as in the Default Arguments section - any item argument left at 0 will instead be set to those values.
You'll also need to call PhantomCloak_Update in your main active script loop.
Item Description:
A ball and chain that follows you around as long as you have it selected. Press the button to pull it towards you. It's damage is proportional to its speed. If it's not moving fast enough, it will do no damage and change color. It can also break certain blocks (defaulting to script flag 1), advancing them to the next combo and potentially dropping an item.
It's a little bit hard to use as your default weapon, but I think it might be fun to design a quest around such a thing.
Instructions: Modify the Integration and Behavior sections as needed. The Integration section has code dealing with compatability between different scripts. The Behavior section specifies the different ball and chain items you may have. Almost every aspect of the item is specified in the various function calls. To make the level 2 ball and chain more damaging, for instance, you'll need to change BallChain_Damage to check for the level 2 item_id and return a different damage value.
Item Description:
The tuning fork is an item that, upon striking a wall or other solid object, causes Link to emit soundwaves for a short period of time. These soundwaves cause various effects to anything they hit, depending on the initial object struck.
It can also be used to detect bombable walls and such, similar to the sword.
This is currently moderately difficult to set-up, and is not recommended for beginners. I might be able to simplify it some, later, but currently you'll need to be familiar with zscript to modify it.
import "std.zh"
import "ffcscript.zh"
import "string.zh"
global script Active{
void run(){
while(true){
if(BeeCooldown>=0)BeeCooldown--;
else if(BeeCooldown<0)
BeeCooldown = 0;
Waitframe();
}
}
}
int BeeCooldown;
bool usingBee = false;//Tells game whether you're currently using the Metroid.
const int BEE_COOLDOWN_REQUIRED = 3600;
const int BEE_SCRIPT_SLOT = 30;
const int BEE_COMBO = 235;
const int BEE_RADIUS =16;
const int BEE_CSET = 8;
const int BEE_MISC_INDEX = 1;
const int BEE_DETECTION_RANGE = 32;
const int BEE_SFX = 66;
item script GoldenBee{
void run(){
if(!usingBee && BeeCooldown ==0){
Game->PlaySound(BEE_SFX);
BeeCooldown = BEE_COOLDOWN_REQUIRED;
usingBee = true;
int Args[8];
ffc launch = RunFFCScriptOrQuit(BEE_SCRIPT_SLOT, Args);
}
else
usingBee = false;
}
}
item script Message{
void run(int m){
Screen->Message(m);
}
}
ffc script Golden_Bee{
void run(){
float angle;
int timer = 10;
npc n;
npc target;
bool isAttacking = false;
int i;
int SoundTimer;
while(true){
for(i=1;i<=Screen->NumNPCs();i++){
n= Screen->LoadNPC(i);
if(n->Misc[BEE_MISC_INDEX] ==0)n->Misc[BEE_MISC_INDEX]= 1;
if(Abs((n->X+8)-(this->X+8))<BEE_DETECTION_RANGE
&&Abs((n->Y+8)-(this->Y+8))<BEE_DETECTION_RANGE && n->Misc[BEE_MISC_INDEX]==1
&& n->Defense[NPCD_FIRE]==NPCDT_NONE){
target = n;
isAttacking = true;
Game->PlaySound(BEE_SFX);
break;
}
}
this->Data = BEE_COMBO;
this->CSet = BEE_CSET;
if(!isAttacking){
this->X = (Link->X+8)+ (2*BEE_RADIUS)* Cos(angle);
this->Y = (Link->Y-8)+ BEE_RADIUS * Sin(angle);
}
else{
if(this->X<target->X)this->X++;
else this->X--;
if(this->Y<target->Y)this->Y++;
else this->Y--;
if(target->HP == 0)isAttacking = false;
else{
if(timer>0)timer--;
if(timer<=0){
target->HP--;
timer = 10;
Game->PlaySound(BEE_SFX);
}
}
}
angle = (angle+1)%360;
SoundTimer = (SoundTimer+1)%60;
if(SoundTimer == O)Game->PlaySound(BEE_SFX);
if(BeeCooldown==0)break;
Waitframe();
}
this->Data = 0;
}
}
// Section 30. ghost.zh
// ghost.zh
// Version 2.8.0
// See ghost.txt for documentation.
// Standard settings -----------------------------------------------------------
// Small (1x1) shadow settings
const int GH_SHADOW_TILE = 27425;
const int GH_SHADOW_CSET = 7;
const int GH_SHADOW_FRAMES = 4;
const int GH_SHADOW_ANIM_SPEED = 8;
const int GH_SHADOW_TRANSLUCENT = 1; // 0 = No, 1 = Yes
const int GH_SHADOW_FLICKER = 0; // 0 = No, 1 = Yes
// Large (2x2) shadow settings
// If GH_LARGE_SHADOW_TILE is 0, large shadows will be disabled
const int GH_LARGE_SHADOW_TILE = 27425; // Top-left corner
const int GH_LARGE_SHADOW_CSET = 7;
const int GH_LARGE_SHADOW_FRAMES = 4;
const int GH_LARGE_SHADOW_ANIM_SPEED = 8;
const int GH_LARGE_SHADOW_MIN_WIDTH = 3; // Enemies must be at least this wide
const int GH_LARGE_SHADOW_MIN_HEIGHT = 3; // and this high to use large shadows
// AutoGhost settings
const int AUTOGHOST_MIN_FFC = 1; // Min: 1, Max: 32
const int AUTOGHOST_MAX_FFC = 32; // Min: 1, Max: 32
const int AUTOGHOST_MIN_ENEMY_ID = 20; // Min: 20, Max: 511
const int AUTOGHOST_MAX_ENEMY_ID = 511; // Min: 20, Max: 511
// Other settings
const int GH_DRAW_OVER_THRESHOLD = 32;
const float GH_GRAVITY = 0.16;
const float GH_TERMINAL_VELOCITY = 3.2;
const int GH_SPAWN_SPRITE = 22; // Min: 0, Max: 255, Default: 22
const int GH_FAKE_Z = 0; // 0 = No, 1 = Yes
const int __GH_FAKE_EWEAPON_Z = 0; // 0 = No, 1 = Yes
const int GH_ENEMIES_FLICKER = 0; // 0 = No, 1 = Yes
const int GH_PREFER_GHOST_ZH_SHADOWS = 0; // 0 = No, 1 = Yes
// Top-left corner of a 4x4 block of blank tiles
const int GH_BLANK_TILE = 65456; // Min: 0, Max: 65456
// Invisible combo with no properties set
const int GH_INVISIBLE_COMBO = 1; // Min: 1, Max: 65279
// Always read script name and combo from the enemy's name,
// freeing up attributes 11 and 12
const int __GH_ALWAYS_USE_NAME = 0;
// End standard settings -------------------------------------------------------
// Advanced settings -----------------------------------------------------------
// AutoGhost will read a script name from the enemy's name if attribute 12
// is set to this. Must be a negative number.
const int AUTOGHOST_READ_NAME = -1;
// When reading a script from the enemy name, this character marks the
// beginning of the script name.
// Default: 64 ( @ )
const int AUTOGHOST_DELIMITER = 64;
// Misc. attribute 11 can be set to this instead of GH_INVISIBLE_COMBO.
// Must be a negative number.
const int __GH_INVISIBLE_ALT = -1;
// This will use the invisible combo, but also set npc->Extend to 3 or 4,
// hiding the initial spawn puff. Must be a negative number.
const int __GH_INVISIBLE_EXTEND = -2;
// If enabled, the FFC will be invisible, and Screen->DrawCombo will be used
// to display enemies.
const int __GH_USE_DRAWCOMBO = 1;
// Enemies flash or flicker for this many frames when hit. This does not
// affect enemies that use the invisible combo.
// Default: 32
const int __GH_FLASH_TIME = 32;
// Enemies will be knocked back for this many frames when hit.
// Default: 16
// Max: 4095
const int __GH_KNOCKBACK_TIME = 16;
// The speed at which enemies are knocked back, in pixels per frame.
// Default: 4
const int __GH_KNOCKBACK_STEP = 4;
// The imprecision setting used when a movement function is called internally
// (except for walking functions).
const int __GH_DEFAULT_IMPRECISION = 2;
// npc->Misc[] index
// Set this so it doesn't conflict with other scripts. Legal values are 0-15.
const int __GHI_NPC_DATA = 15;
// eweapon->Misc[] indices
// These must be unique numbers between 0 and 15.
const int __EWI_FLAGS = 15; // Every index but this one can be used by non-ghost.zh EWeapons
const int __EWI_ID = 3;
const int __EWI_XPOS = 4;
const int __EWI_YPOS = 5;
const int __EWI_WORK = 6;
const int __EWI_WORK_2 = 7; // Only used by a few movement types
const int __EWI_MOVEMENT = 8;
const int __EWI_MOVEMENT_ARG = 9;
const int __EWI_MOVEMENT_ARG_2 = 10;
const int __EWI_LIFESPAN = 11;
const int __EWI_LIFESPAN_ARG = 12;
const int __EWI_ON_DEATH = 13;
const int __EWI_ON_DEATH_ARG = 14;
// These are only used by dummy EWeapons;
// they can use the same values as __EWI_XPOS and __EWI_YPOS
const int __EWI_DUMMY_SOUND = 2;
const int __EWI_DUMMY_STEP = 4;
const int __EWI_DUMMY_SPRITE = 5;
// Returns true if the given combo should be considered a pit.
bool __IsPit(int combo)
{
return IsPit(combo); // std.zh implementation by default
}
// Returns true if enemies are visible on screens with the
// "All Enemies Are Invisible" flag enabled
bool __HaveAmulet()
{
return Link->Item[I_AMULET1] || Link->Item[I_AMULET2];
}
// End advanced settings -------------------------------------------------------
import "ghost_zh/2.8/common.zh"
import "ghost_zh/2.8/deprecated.zh"
import "ghost_zh/2.8/drawing.zh"
import "ghost_zh/2.8/eweapon.zh"
import "ghost_zh/2.8/eweaponDeath.zh"
import "ghost_zh/2.8/eweaponMovement.zh"
import "ghost_zh/2.8/flags.zh"
import "ghost_zh/2.8/global.zh"
import "ghost_zh/2.8/init.zh"
import "ghost_zh/2.8/modification.zh"
import "ghost_zh/2.8/movement.zh"
import "ghost_zh/2.8/other.zh"
import "ghost_zh/2.8/update.zh"
import "ghost_zh/2.8/scripts.z"
Having played his DotM I had to go with the Phantom Cloak cause I loved it. xD
On first thought I thought it may be a bit OP for a starting item. But then playing his dungeon he showed great ways on how to use it without it being too too OP. It could in some ways be a replacement to the step ladder. And it has extra uses. That make it good for combat and puzzles. So yeah. Phantom Cloak for me.
In case anyone hasn't guessed, my submission was rushed because I wanted there to be more than one person's work in this thing and didn't want it to just die out.
I haven't tried any of grayswandir's items yet, but I plan to. When I do, I'll review them.
I've already thought of many ways to improve mine, including having it persist between screens until a timer has passed; then having the bee fly away like it does in LTTP.
Setup is fairly easy. Assign the script to a slot, create appropriate combos and sounds and make sure all your constants are set up properly. It's an item script for the action slot that runs an ffc script, though it has a global script to track the timer at all times.