Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import "std.zh"
- import "string.zh"
- import "ghost.zh"
- import "ffcscript.zh"
- import "stdextra.zh"
- import "laser.zh"
- //global constants, arrays etc, etc...
- const int SFX_GBSHIELD = 17; //Shield active SFX
- //Arrays -Z: Needs new save for this version.
- int ___GRAM[1024]; //Global RAM
- bool Owns[256];
- //Array Index Constants.
- const int SHIELD_BUTTON = 500; //Array Index
- const int SHIELD_USES_L = 1;
- const int SHIELD_USES_R = 2;
- const int SHIELD_CRRENT_ITEM = 501;
- int MooshPit[16];
- const int MP_LASTX = 0;
- const int MP_LASTY = 1;
- const int MP_LASTDMAP = 2;
- const int MP_LASTSCREEN = 3;
- const int MP_ENTRYX = 4;
- const int MP_ENTRYY = 5;
- const int MP_ENTRYDMAP = 6;
- const int MP_ENTRYSCREEN = 7;
- const int MP_FALLX = 8;
- const int MP_FALLY = 9;
- const int MP_FALLTIMER = 10;
- const int MP_FALLSTATE = 11;
- const int MP_DAMAGETYPE = 12;
- const int CT_HOLELAVA = 128; //Combo type for pits (No Ground Enemies by default)
- const int CF_LAVA = 98; //Combo flag marking pits as lava (Script 1 by default)
- const int SPR_FALLHOLE = 88; //Sprite for Link falling in a hole
- const int SPR_FALLLAVA = 89; //Sprite for Link falling in lava
- const int SFX_FALLHOLE = 38; //Sound for falling in a hole
- const int SFX_FALLLAVA = 13; //Sound for falling in lava
- const int DAMAGE_FALLHOLE = 8; //How much damage pits deal (1/2 heart default)
- const int DAMAGE_FALLLAVA = 16; //How much damage lava deals (1 heart default)
- const int FFC_MOOSHPIT_AUTOWARPA = 32; //FFC that turns into an auto side warp combo when you fall in a pit
- const int CMB_MOOSHPIT_AUTOWARPA = 2; //Combo number of an invisible Auto Side Warp A combo
- const int SF_MISC_MOOSHPITWARP = 2; //Number of the screen flag under the Misc. section that makes pits warp (Script 1 by default)
- //All pit warps use Side Warp A
- //Width and height of Link's hitbox for colliding with pits
- const int MOOSHPIT_LINKHITBOXWIDTH = 2;
- const int MOOSHPIT_LINKHITBOXHEIGHT = 2;
- //Width and height of Link's hitbox for colliding with pits/lava in sideview
- const int MOOSHPIT_SIDEVIEW_LINKHITBOXWIDTH = 2;
- const int MOOSHPIT_SIDEVIEW_LINKHITBOXHEIGHT = 2;
- //moosh pit constsants
- global script Active{
- void run(){
- bool shieldOn;
- StartGhostZH();
- MooshPit_Init();
- while(true){
- DoShield( CurShield() );
- UpdateGhostZH1();
- MooshPit_Update();
- Waitdraw();
- UpdateGhostZH2();
- Waitframe();
- }
- }
- }
- //global funtions go here
- //Sets the btton sed by the shield.
- void ShieldButton(int button){
- ___GRAM[SHIELD_BUTTON] = button;
- }
- //Gets crrent shield btton.
- int ShieldButton(){ return ___GRAM[SHIELD_BUTTON]; }
- //Checks if the player is pressing a button for a shield.
- bool PressShield(){
- if ( ( ShieldButton()== SHIELD_USES_L && Link->InputL ) || ( ShieldButton() == SHIELD_USES_R && Link->InputR ) ) { return true; }
- return false;
- }
- //Checks or sets the current shield item.
- int CurShield(){ return ___GRAM[SHIELD_CRRENT_ITEM]; }
- void CurShield(int itm){ ___GRAM[SHIELD_CRRENT_ITEM] = itm; }
- //Runs shield on button press.
- void DoShield(int itm){
- if ( PressShield() && !Link->Item[itm] ) { Link->Item[itm] = true; Game->PlaySound(SFX_GBSHIELD); }
- if ( !PressShield() && Link->Item[itm] ) { Link->Item[itm] = false; Game->PlaySound(SFX_GBSHIELD); }
- }
- bool Owns(int itm){ return Owns[itm]; }
- bool MooshPit_OnPit(int LinkX, int LinkY){
- if(MooshPit_OnFFC(LinkX, LinkY)){
- return false;
- }
- bool sideview;
- if(Screen->Flags[SF_ROOMTYPE]&100b)
- sideview = true;
- //wew lad
- int width = MOOSHPIT_LINKHITBOXWIDTH;
- int height = MOOSHPIT_LINKHITBOXHEIGHT;
- for(int x=0; x<=1; x++){
- for(int y=0; y<=1; y++){
- int X; int Y;
- if(sideview){ //Hitbox functions differently in sideview
- width = MOOSHPIT_SIDEVIEW_LINKHITBOXWIDTH;
- height = MOOSHPIT_SIDEVIEW_LINKHITBOXHEIGHT;
- X = LinkX+7-width/2+width;
- Y = LinkY+7-height/2+height;
- }
- else{
- X = LinkX+7-width/2+width;
- Y = LinkY+11-height/2+height;
- }
- //If one corner of Link's hitbox isn't on a pit, return false
- if(Screen->ComboT[ComboAt(X, Y)]!=CT_HOLELAVA){
- return false;
- }
- }
- }
- return true;
- }
- bool MooshPit_OnFFC(int LinkX, int LinkY){
- for(int i=1; i<=32; i++){ //Cycle through every FFC
- ffc f = Screen->LoadFFC(i);
- //Check if the FFC is solid
- if(f->Data>0&&!f->Flags[FFCF_CHANGER]&&!f->Flags[FFCF_ETHEREAL]){
- //Check if Link collides with the FFC
- if(RectCollision(LinkX+4, LinkY+9, LinkX+11, LinkY+14, f->X, f->Y, f->X+f->EffectWidth-1, f->Y+f->EffectHeight-1)){
- return true;
- }
- }
- }
- //If Link doesn't collide with any FFC, return false
- return false;
- }
- void MooshPit_Init(){
- MooshPit[MP_LASTX] = Link->X;
- MooshPit[MP_LASTY] = Link->Y;
- MooshPit[MP_LASTDMAP] = Game->GetCurDMap();
- MooshPit[MP_LASTSCREEN] = Game->GetCurDMapScreen();
- MooshPit[MP_ENTRYX] = Link->X;
- MooshPit[MP_ENTRYY] = Link->Y;
- MooshPit[MP_ENTRYDMAP] = Game->GetCurDMap();
- MooshPit[MP_ENTRYSCREEN] = Game->GetCurDMapScreen();
- MooshPit[MP_FALLSTATE] = 0;
- MooshPit[MP_FALLTIMER] = 0;
- Link->CollDetection = true;
- Link->Invisible = false;
- }
- void MooshPit_Update(){
- bool isWarp;
- if(Screen->Flags[SF_MISC]&(1<<SF_MISC_MOOSHPITWARP))
- isWarp = true;
- bool sideview;
- if(Screen->Flags[SF_ROOMTYPE]&100b)
- sideview = true;
- if(Link->Action!=LA_SCROLLING){
- //Update the entry point whenever the screen changes
- if(MooshPit[MP_ENTRYDMAP]!=Game->GetCurDMap()||MooshPit[MP_ENTRYSCREEN]!=Game->GetCurDMapScreen()){
- MooshPit[MP_ENTRYX] = Link->X;
- MooshPit[MP_ENTRYY] = Link->Y;
- MooshPit[MP_ENTRYDMAP] = Game->GetCurDMap();
- MooshPit[MP_ENTRYSCREEN] = Game->GetCurDMapScreen();
- }
- if(MooshPit[MP_FALLSTATE]==0){ //Not falling in pit
- if(Link->Z<=0&&MooshPit_OnPit(Link->X, Link->Y)){ //If Link steps on a pit
- int underLink;
- if(!sideview)
- underLink = ComboAt(Link->X+8, Link->Y+12);
- else
- underLink = ComboAt(Link->X+8, Link->Y+8);
- lweapon fall;
- Link->X = ComboX(underLink);
- Link->Y = ComboY(underLink);
- //Check if the combo is lava
- if(ComboFI(underLink, CF_LAVA)){
- //Play sound and display animation
- Game->PlaySound(SFX_FALLLAVA);
- fall = CreateLWeaponAt(LW_SCRIPT10, Link->X, Link->Y);
- fall->UseSprite(SPR_FALLLAVA);
- fall->CollDetection = false;
- fall->DeadState = fall->ASpeed*fall->NumFrames;
- //Mark as lava damage
- MooshPit[MP_DAMAGETYPE] = 1;
- }
- //Otherwise it's a pit
- else{
- //Play sound and display animation
- Game->PlaySound(SFX_FALLHOLE);
- fall = CreateLWeaponAt(LW_SCRIPT10, Link->X, Link->Y);
- fall->UseSprite(SPR_FALLHOLE);
- fall->CollDetection = false;
- fall->DeadState = fall->ASpeed*fall->NumFrames;
- //Mark as hole damage
- MooshPit[MP_DAMAGETYPE] = 0;
- }
- MooshPit[MP_FALLX] = Link->X;
- MooshPit[MP_FALLY] = Link->Y;
- //Cooldown should last as long as the fall animation
- MooshPit[MP_FALLSTATE] = 1;
- MooshPit[MP_FALLTIMER] = fall->DeadState;
- //Render Link invisible and intangible
- Link->Invisible = true;
- Link->CollDetection = false;
- NoAction();
- }
- else{ //All other times, while Link is on solid ground, record Link's last position
- if(sideview){
- //Link has no Z value in sideview, so we check if he's on a platform instead
- if(OnSidePlatform(Link->X, Link->Y)){
- MooshPit[MP_LASTDMAP] = Game->GetCurDMap();
- MooshPit[MP_LASTSCREEN] = Game->GetCurDMapScreen();
- MooshPit[MP_LASTX] = Link->X;
- MooshPit[MP_LASTY] = Link->Y;
- }
- }
- else{
- if(Link->Z<=0){
- MooshPit[MP_LASTDMAP] = Game->GetCurDMap();
- MooshPit[MP_LASTSCREEN] = Game->GetCurDMapScreen();
- MooshPit[MP_LASTX] = Link->X;
- MooshPit[MP_LASTY] = Link->Y;
- }
- }
- }
- }
- else if(MooshPit[MP_FALLSTATE]==1){ //Falling animation
- if(MooshPit[MP_FALLTIMER]>0)
- MooshPit[MP_FALLTIMER]--;
- Link->Jump = 0;
- Link->Z = 0;
- //Keep Link invisible just in case
- Link->Invisible = true;
- Link->CollDetection = false;
- NoAction();
- if(MooshPit[MP_FALLTIMER]==0){
- if(!isWarp||MooshPit[MP_DAMAGETYPE]==1){ //If the pit isn't a warp, deal damage and move Link back to the return point
- //If the entry would dump Link back in the pit, dump him out at the failsafe position
- if(MooshPit_OnPit(MooshPit[MP_ENTRYX], MooshPit[MP_ENTRYY])){
- Link->X = MooshPit[MP_LASTX];
- Link->Y = MooshPit[MP_LASTY];
- //If the failsafe position was on a different screen, warp there
- if(Game->GetCurDMap()!=MooshPit[MP_LASTDMAP]||Game->GetCurDMapScreen()!=MooshPit[MP_LASTSCREEN]){
- Link->PitWarp(MooshPit[MP_LASTDMAP], MooshPit[MP_LASTSCREEN]);
- }
- Link->Invisible = false;
- Link->CollDetection = true;
- }
- else{
- //Move Link to the start and make him visible
- Link->X = MooshPit[MP_ENTRYX];
- Link->Y = MooshPit[MP_ENTRYY];
- Link->Invisible = false;
- Link->CollDetection = true;
- }
- //Subtract HP based on damage type
- if(MooshPit[MP_DAMAGETYPE]==1)
- Link->HP -= DAMAGE_FALLLAVA;
- else
- Link->HP -= DAMAGE_FALLHOLE;
- //Play hurt sound and animation
- Link->Action = LA_GOTHURTLAND;
- Link->HitDir = -1;
- Game->PlaySound(SFX_OUCH);
- MooshPit[MP_FALLSTATE] = 0;
- }
- else{
- MooshPit[MP_FALLSTATE] = 2;
- MooshPit[MP_FALLTIMER] = 1;
- ffc warp = Screen->LoadFFC(FFC_MOOSHPIT_AUTOWARPA);
- warp->Data = CMB_MOOSHPIT_AUTOWARPA;
- warp->Flags[FFCF_CARRYOVER] = false;
- }
- }
- }
- else if(MooshPit[MP_FALLSTATE]==2){ //Just warped
- if(sideview){
- Link->X = MooshPit[MP_FALLX];
- Link->Y = 0;
- }
- else{
- Link->X = MooshPit[MP_FALLX];
- Link->Y = MooshPit[MP_FALLY];
- Link->Z = 176;
- }
- Link->Invisible = false;
- Link->CollDetection = true;
- MooshPit[MP_FALLSTATE] = 0;
- MooshPit[MP_FALLTIMER] = 0;
- }
- }
- }
- //ffc scripts------------------------------------------------------------------------------------------------------------@ffcs
- const int RESET_NPC_LAYER_ON_ENTRY = 1; //This fix will replace all CMB_NPC_SOLID tiles with CMB_NPC_HIDDEN
- //when entering the screen. This should prevent problems with shared
- //layers. If you don't want this fix, set it to 0.
- const int LAYER_NPC = 2; //The layer NPCs use for solid combos
- const int CMB_NPC_HIDDEN = 4; //Non-solid combo used for hidden NPCs
- const int CMB_NPC_SOLID = 1; //Solid combo placed under visible NPCs
- const int LAYER_NPC_CANTALK = 4; //The layer used for the speech bubble
- const int CMB_NPC_CANTALK = 0; //The combo used for the speech bubble
- const int CS_NPC_CANTALK = 8; //The CSet used for the speech bubble
- const int NPCBT_NONE = 0; //Regular NPCs
- const int NPCBT_FACELINK = 1; //NPCs that turn to face Link
- const int NPCBT_GUARDH = 2; //NPCs that move along a horizontal path
- const int NPCBT_GUARDV = 3; //NPCs that move along a vertical path
- ffc script NPCScript{
- void run(int String, int ItemCheck, int Type, int Arg1, int Arg2, int NoSolid, int Script){
- //Stores the NPC's combo, hides it
- int Combo = this->Data;
- this->Data = CMB_NPC_HIDDEN;
- //Waits until the NPC should appear and shows it
- if(ItemCheck<0){
- while(!Link->Item[Abs(ItemCheck)]){
- Waitframe();
- }
- this->Data = Combo;
- if(Type==NPCBT_FACELINK){
- this->Data = Combo + Arg1;
- }
- }
- else if(ItemCheck>0){
- if(!Link->Item[Abs(ItemCheck)]){
- this->Data = Combo;
- if(Type==NPCBT_FACELINK){
- this->Data = Combo + Arg1;
- }
- }
- }
- else if(ItemCheck==0){
- this->Data = Combo;
- if(Type==NPCBT_FACELINK){
- this->Data = Combo + Arg1;
- }
- }
- //Saves the width and height of the FFC for collision checks
- int Width = 16;
- int Height = 16;
- if(this->EffectWidth!=16)
- Width = this->EffectWidth;
- else if(this->TileWidth>1)
- Width = this->TileWidth*16;
- if(this->EffectHeight!=16)
- Height = this->EffectHeight;
- else if(this->TileHeight>1)
- Height = this->TileHeight*16;
- //Wait until the screen is done scrolling to avoid a weird ZC crashing bug
- Waitframe();
- while(Link->Action==LA_SCROLLING){
- Waitframe();
- }
- //Shared Layer Fix
- if(RESET_NPC_LAYER_ON_ENTRY==1){
- if(Screen->LoadFFC(FindFFCRunning(this->Script))==this){
- for(int i=0; i<176; i++){
- if(GetLayerComboD(LAYER_NPC, i)==CMB_NPC_SOLID){
- SetLayerComboD(LAYER_NPC, i, CMB_NPC_HIDDEN);
- }
- }
- }
- }
- //Sets the space below the NPC or the space a guard NPC occupies to be solid
- if(LAYER_NPC>-1&&NoSolid==0){
- if(Type==NPCBT_GUARDH){
- for(int x=Arg1; x<=Arg2+this->TileWidth-1; x++){
- for(int y=Floor(this->Y/16); y<=Floor(this->Y/16)+this->TileHeight-1; y++){
- SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_SOLID);
- }
- }
- }
- else if(Type==NPCBT_GUARDV){
- for(int x=Floor(this->X/16); x<=Floor(this->X/16)+this->TileWidth-1; x++){
- for(int y=Arg1; y<=Arg2+this->TileHeight-1; y++){
- SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_SOLID);
- }
- }
- }
- else{
- for(int x=Floor(this->X/16); x<=Floor(this->X/16)+this->TileWidth-1; x++){
- for(int y=Floor(this->Y/16); y<=Floor(this->Y/16)+this->TileHeight-1; y++){
- SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_SOLID);
- }
- }
- }
- }
- while(true){
- //Removes NPCs if Link has the required item
- if(ItemCheck>0){
- if(Link->Item[ItemCheck]){
- this->Data = CMB_NPC_HIDDEN;
- if(LAYER_NPC>-1&&NoSolid==0){
- if(Type==NPCBT_GUARDH){
- for(int x=Arg1; x<=Arg2+this->TileWidth-1; x++){
- for(int y=Floor(this->Y/16); y<=Floor(this->Y/16)+this->TileHeight-1; y++){
- SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_HIDDEN);
- }
- }
- }
- else if(Type==NPCBT_GUARDV){
- for(int x=Floor(this->X/16); x<=Floor(this->X/16)+this->TileWidth-1; x++){
- for(int y=Arg1; y<=Arg2+this->TileHeight-1; y++){
- SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_HIDDEN);
- }
- }
- }
- else{
- for(int x=Floor(this->X/16); x<=Floor(this->X/16)+this->TileWidth-1; x++){
- for(int y=Floor(this->Y/16); y<=Floor(this->Y/16)+this->TileHeight-1; y++){
- SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_HIDDEN);
- }
- }
- }
- }
- Quit();
- }
- }
- //Handles animation for turning NPCs
- if(Type==NPCBT_FACELINK&&(Link->X>0&&Link->X<240&&Link->Y>0&&Link->Y<160)){
- if(Distance(CenterLinkX(), CenterLinkY(), CenterX(this), CenterY(this))<Arg2)
- this->Data = Combo + AngleDir4(Angle(CenterX(this), CenterY(this), CenterLinkX(), CenterLinkY()));
- else
- this->Data = Combo + Arg1;
- }
- //Handles movement for guard NPCs
- else if(Type==NPCBT_GUARDH){
- if(Link->X>16*Arg1-32&&Link->X<16*Arg2+32&&Link->Y>this->Y-32&&Link->Y<this->Y+32){
- this->X = Clamp(this->X+(-this->X + Link->X)/4, 16*Arg1, 16*Arg2);
- }
- }
- else if(Type==NPCBT_GUARDV){
- if(Link->X>this->X-32&&Link->X<this->X+32&&Link->Y>16*Arg1-32&&Link->Y<16*Arg2+32){
- this->Y = Clamp(this->Y+(-this->Y + Link->Y)/4, 16*Arg1, 16*Arg2);
- }
- }
- //Facing Up
- if(Link->Dir==DIR_UP&&Link->Y>=this->Y&&Link->Y<=this->Y+Height-8&&Link->X>=this->X-8&&Link->X<=this->X+Width-8){
- if(CMB_NPC_CANTALK>0)
- Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
- if(Link->PressA){
- Link->InputA = false;
- Link->PressA = false;
- Screen->Message(String);
- if(Script>0){
- RunFFCScript(Script, 0);
- }
- }
- }
- //Facing Down
- else if(Link->Dir==DIR_DOWN&&Link->Y>=this->Y-16&&Link->Y<=this->Y+Height-16&&Link->X>=this->X-8&&Link->X<=this->X+Width-8){
- if(CMB_NPC_CANTALK>0)
- Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
- if(Link->PressA){
- Link->InputA = false;
- Link->PressA = false;
- Screen->Message(String);
- if(Script>0){
- RunFFCScript(Script, 0);
- }
- }
- }
- //Facing Left
- else if(Link->Dir==DIR_LEFT&&Link->Y>=this->Y-8&&Link->Y<=this->Y+Height-8&&Link->X>=this->X&&Link->X<=this->X+Width){
- if(CMB_NPC_CANTALK>0)
- Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
- if(Link->PressA){
- Link->InputA = false;
- Link->PressA = false;
- Screen->Message(String);
- if(Script>0){
- RunFFCScript(Script, 0);
- }
- }
- }
- //Facing Right
- else if(Link->Dir==DIR_RIGHT&&Link->Y>=this->Y-8&&Link->Y<=this->Y+Height-8&&Link->X>=this->X-16&&Link->X<=this->X+Width-16){
- if(CMB_NPC_CANTALK>0)
- Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
- if(Link->PressA){
- Link->InputA = false;
- Link->PressA = false;
- Screen->Message(String);
- if(Script>0){
- RunFFCScript(Script, 0);
- }
- }
- }
- Waitframe();
- }
- }
- }
- ffc script NPCScript_Simple{
- void run(int String, int Script, int D0, int D1, int D2, int D3, int D4, int D5){
- //Saves the width and height of the FFC for collision checks
- int Width = 16;
- int Height = 16;
- if(this->EffectWidth!=16)
- Width = this->EffectWidth;
- else if(this->TileWidth>1)
- Width = this->TileWidth*16;
- if(this->EffectHeight!=16)
- Height = this->EffectHeight;
- else if(this->TileHeight>1)
- Height = this->TileHeight*16;
- while(true){
- //Facing Up
- if(Link->Dir==DIR_UP&&Link->Y>=this->Y&&Link->Y<=this->Y+Height-8&&Link->X>=this->X-8&&Link->X<=this->X+Width-8){
- if(CMB_NPC_CANTALK>0)
- Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
- if(Link->PressA){
- Link->InputA = false;
- Link->PressA = false;
- Screen->Message(String);
- if(Script>0){
- int Args[8] = {D0, D1, D2, D3, D4, D5};
- RunFFCScript(Script, Args);
- }
- }
- }
- //Facing Down
- else if(Link->Dir==DIR_DOWN&&Link->Y>=this->Y-16&&Link->Y<=this->Y+Height-16&&Link->X>=this->X-8&&Link->X<=this->X+Width-8){
- if(CMB_NPC_CANTALK>0)
- Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
- if(Link->PressA){
- Link->InputA = false;
- Link->PressA = false;
- Screen->Message(String);
- if(Script>0){
- int Args[8] = {D0, D1, D2, D3, D4, D5};
- RunFFCScript(Script, Args);
- }
- }
- }
- //Facing Left
- else if(Link->Dir==DIR_LEFT&&Link->Y>=this->Y-8&&Link->Y<=this->Y+Height-8&&Link->X>=this->X&&Link->X<=this->X+Width){
- if(CMB_NPC_CANTALK>0)
- Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
- if(Link->PressA){
- Link->InputA = false;
- Link->PressA = false;
- Screen->Message(String);
- if(Script>0){
- int Args[8] = {D0, D1, D2, D3, D4, D5};
- RunFFCScript(Script, Args);
- }
- }
- }
- //Facing Right
- else if(Link->Dir==DIR_RIGHT&&Link->Y>=this->Y-8&&Link->Y<=this->Y+Height-8&&Link->X>=this->X-16&&Link->X<=this->X+Width-16){
- if(CMB_NPC_CANTALK>0)
- Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
- if(Link->PressA){
- Link->InputA = false;
- Link->PressA = false;
- Screen->Message(String);
- if(Script>0){
- int Args[8] = {D0, D1, D2, D3, D4, D5};
- RunFFCScript(Script, Args);
- }
- }
- }
- Waitframe();
- }
- }
- }
- const int D_TRADE = 0; //Screen->D value used for the trade sequence state
- ffc script TradeSequence{
- void run(int CheckItem, int TradeItem, int NoItemString, int HasItemString, int TradedString){
- //Check if the player has already traded
- if(Screen->D[D_TRADE]==0){
- //If player hasn't traded and has the required item, play HasItemString, give the new item, and take the old item
- if(Link->Item[CheckItem]){
- Screen->Message(HasItemString);
- WaitNoAction();
- item itm = CreateItemAt(TradeItem, Link->X, Link->Y);
- itm->Pickup = IP_HOLDUP;
- Link->Item[CheckItem] = false;
- Screen->D[D_TRADE] = 1;
- WaitNoAction();
- }
- //If player hasn't traded and doesn't have the required item, play NoItemString
- else{
- Screen->Message(NoItemString);
- WaitNoAction();
- }
- }
- //If the player has already traded, play TradedString
- else{
- Screen->Message(TradedString);
- WaitNoAction();
- }
- }
- }
- // D0: Set this to 1 if you have a Normal Item set.
- // D1: Set this to 1 if you have a Special Item set.
- // D2: Set this to 1 if you have a Normal Chest set.
- // D3: Set this to 1 if you have a Locked Chest set.
- // D4: Set this to 1 if you have a Boss Chest set.
- const int COMPASS_SFX = 65;
- ffc script NyroxCompassBeep{
- void run(int arg1, int arg2, int arg3, int arg4, int arg5){
- if(GetLevelItem(LI_COMPASS)){
- if(!Screen->State[ST_ITEM] && (arg1 == 1)){
- Game->PlaySound(COMPASS_SFX);
- }
- else if(!Screen->State[ST_SPECIALITEM]&& (arg2 == 1)){
- Game->PlaySound(COMPASS_SFX);
- }
- else if(!Screen->State[ST_CHEST]&& (arg3 == 1)){
- Game->PlaySound(COMPASS_SFX);
- }
- else if (!Screen->State[ST_LOCKEDCHEST] && (arg4 == 1)){
- Game->PlaySound(COMPASS_SFX);
- }
- else if(!Screen->State[ST_BOSSCHEST]&& (arg5 == 1)){
- Game->PlaySound(COMPASS_SFX);
- }
- }
- }
- }
- //item scripts-----------------------------------------------------------------------------------------------------@Item
- //Shield Pick-up. D0 is the message, D1 is the ID of this item.
- item script Zoria_Shield_Pickup{
- void run(int msg, int item_id){
- if ( msg > 0 ) { Screen->Message(msg); }
- if ( item_id > 0 && item_id < 256 ) { Owns[item_id] = true; }
- CurShield(item_id);
- }
- }
- //Modified to use new system. -Z
- item script gbshield{
- void run ( int shield , int buttonsfx ){
- CurShield(shield);
- if ( ShieldButton() == SHIELD_USES_L ) { ShieldButton(SHIELD_USES_R); if ( buttonsfx > 0 ) Game->PlaySound(buttonsfx); }
- else { ShieldButton(SHIELD_USES_L); if ( buttonsfx > 0 ) Game->PlaySound(buttonsfx); }
- }
- }
- item script Message{
- void run(int m){
- Screen->Message(m);
- }
- }
- //enemy scirpts--------------------------------------------------------------------------------------------------@enemy
- //Three colors used for the lasers
- const int C_EZB_LASER1 = 0x77;
- const int C_EZB_LASER2 = 0x76;
- const int C_EZB_LASER3 = 0x7C;
- const int SFX_EZB_TELEPORT = 66; //Sound when a boss teleports
- const int SFX_EZB_LASER = 37; //Sound when a laser is fired
- const int EZBF_4WAY = 00000001b;
- const int EZBF_8WAY = 00000010b;
- const int EZBF_FLYING = 00000100b;
- const int EZBF_AQUATIC = 00001000b;
- const int EZBF_NOFALL = 00010000b;
- const int EZBF_EXPLODEEATH = 00100000b;
- const int EZBF_FACELINK = 01000000b;
- const int EZBF_UNBLOCKABLE = 10000000b;
- ffc script EZBoss{
- void run(int enemyid){
- int i; int j; int k; int angle; int dist; int x; int y;
- npc ghost = Ghost_InitAutoGhost(this, enemyid);
- int movementStyle = ghost->Attributes[0];
- int attack1 = ghost->Attributes[1];
- int attack2 = ghost->Attributes[2];
- int attack3 = ghost->Attributes[3];
- int special = ghost->Attributes[5];
- int size = ghost->Attributes[6];
- int fireSFX = ghost->Attributes[7];
- int fireSPR = ghost->Attributes[8];
- int flags = ghost->Attributes[9];
- int w = size&1111b;
- int h = (size>>4)&1111b;
- if(h==0)
- h = w;
- w = Clamp(w, 1, 4);
- h = Clamp(h, 1, 4);
- int combo = ghost->Attributes[10];
- Ghost_Transform(this, ghost, -1, -1, w, h);
- if(flags&EZBF_8WAY)
- Ghost_SetFlag(GHF_8WAY);
- else if(flags&EZBF_4WAY)
- Ghost_SetFlag(GHF_4WAY);
- if(flags&EZBF_NOFALL)
- Ghost_SetFlag(GHF_NO_FALL);
- if(flags&EZBF_FLYING){
- Ghost_SetFlag(GHF_IGNORE_ALL_TERRAIN);
- Ghost_SetFlag(GHF_FLYING_ENEMY);
- }
- else if(flags&EZBF_AQUATIC){
- Ghost_SetFlag(GHF_WATER_ONLY);
- }
- int stepCounter = -1;
- int attackCooldown = ghost->Haltrate*10;
- int stepAngle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
- int vX; int vY;
- if(movementStyle==4){
- angle = Rand(360);
- vX = VectorX(ghost->Step/100, angle);
- vY = VectorY(ghost->Step/100, angle);
- }
- while(true){
- bool attackCond = false;
- //Handle Movement
- if(movementStyle==0){ //4 Way Halting Walk
- stepCounter = Ghost_HaltingWalk4(stepCounter, ghost->Step, ghost->Rate, ghost->Homing, ghost->Hunger, ghost->Haltrate, 48);
- if(stepCounter==16)
- attackCond = true;
- }
- else if(movementStyle==1){ //4 Way Constant Walk
- stepCounter = Ghost_ConstantWalk4(stepCounter, ghost->Step, ghost->Rate, ghost->Homing, ghost->Hunger);
- if(attackCooldown>0)
- attackCooldown--;
- else if(Rand(24)==0)
- attackCond = true;
- }
- else if(movementStyle==2){ //8 Way Constant Walk
- stepCounter = Ghost_ConstantWalk8(stepCounter, ghost->Step, ghost->Rate, ghost->Homing, ghost->Hunger);
- if(attackCooldown>0)
- attackCooldown--;
- else if(Rand(24)==0)
- attackCond = true;
- }
- else if(movementStyle==3){ //Homing in on Link
- if(Distance(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())>8){
- EZB_FaceLink(this, ghost);
- Ghost_MoveAtAngle(Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY()), ghost->Step/100, 0);
- }
- if(attackCooldown>0)
- attackCooldown--;
- else if(Rand(24)==0)
- attackCond = true;
- }
- else if(movementStyle==4){ //Wall Bounce
- Ghost_MoveXY(vX, vY, 0);
- if((vX<0&&!Ghost_CanMove(DIR_LEFT, 1, 0)) || (vX>0&&!Ghost_CanMove(DIR_RIGHT, 1, 0)))
- vX = -vX;
- if((vY<0&&!Ghost_CanMove(DIR_UP, 1, 0)) || (vY>0&&!Ghost_CanMove(DIR_DOWN, 1, 0)))
- vY = -vY;
- Ghost_Dir = EZB_AngleDir(this, ghost, Angle(0, 0, vX*10, vY*10));
- if(flags&EZBF_FACELINK)
- EZB_FaceLink(this, ghost);
- if(attackCooldown>0)
- attackCooldown--;
- else if(Rand(24)==0)
- attackCond = true;
- }
- else if(movementStyle==5){ //Periodic Reaim
- Ghost_MoveAtAngle(stepAngle, ghost->Step/100, 0);
- Ghost_Dir = EZB_AngleDir(this, ghost, stepAngle);
- if(flags&EZBF_FACELINK)
- EZB_FaceLink(this, ghost);
- if(attackCooldown>0)
- attackCooldown--;
- else if(Rand(24)==0)
- attackCond = true;
- stepCounter++;
- if(stepCounter>80&&Rand(10)==0){
- stepAngle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
- stepCounter = 0;
- }
- }
- else if(movementStyle==6){ //Lazy chase
- float homing = ghost->Homing*0.001;
- float topSpeed = ghost->Step*0.01;
- vX = Clamp(vX+Sign(CenterLinkX()-CenterX(ghost))*homing, -topSpeed, topSpeed);
- vY = Clamp(vY+Sign(CenterLinkY()-CenterY(ghost))*homing, -topSpeed, topSpeed);
- Ghost_MoveXY(vX, vY, 0);
- if((vX<0&&!Ghost_CanMove(DIR_LEFT, 1, 0)) || (vX>0&&!Ghost_CanMove(DIR_RIGHT, 1, 0)))
- vX = -vX;
- if((vY<0&&!Ghost_CanMove(DIR_UP, 1, 0)) || (vY>0&&!Ghost_CanMove(DIR_DOWN, 1, 0)))
- vY = -vY;
- Ghost_Dir = EZB_AngleDir(this, ghost, Angle(0, 0, vX*10, vY*10));
- if(flags&EZBF_FACELINK)
- EZB_FaceLink(this, ghost);
- if(attackCooldown>0)
- attackCooldown--;
- else if(Rand(24)==0)
- attackCond = true;
- }
- else if(movementStyle==7){ //Hopping
- EZB_Waitframes(this, ghost, Choose(24, 32, 48));
- stepAngle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())+Rand(-30, 30);
- Game->PlaySound(SFX_JUMP);
- Ghost_Jump = 2.6;
- while(Ghost_Jump>0||Ghost_Z>0){
- Ghost_Dir = EZB_AngleDir(this, ghost, stepAngle);
- Ghost_MoveAtAngle(stepAngle, ghost->Step/100, 0);
- if(flags&EZBF_FACELINK)
- EZB_FaceLink(this, ghost);
- EZB_Waitframe(this, ghost);
- }
- if(Rand(ghost->Rate)==0)
- attackCond = true;
- }
- else if(movementStyle==8){ //Teleport
- EZB_Waitframes(this, ghost, Choose(32, 48, 96));
- EZB_Teleport(this, ghost);
- if(Rand(ghost->Rate)==0)
- attackCond = true;
- }
- if(attackCond&&attack1){
- //Select an attack
- int attack;
- if(attack2==0)
- attack = attack1;
- else if(attack3==0)
- attack = Choose(attack1, attack2);
- else
- attack = Choose(attack1, attack2, attack3);
- if(attack==1){ //Dash
- angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
- EZB_FaceLink(this, ghost);
- EZB_Waitframes(this, ghost, 30);
- while(EZB_CanMoveAngle(angle)){
- Ghost_MoveAtAngle(angle, 5, 0);
- EZB_Trail(this, ghost);
- EZB_Waitframe(this, ghost);
- }
- }
- else if(attack==2){ //Shoot (Directional)
- EZB_FiringAnim(this, ghost);
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, EZB_DirAngle(Ghost_Dir), 150);
- EZB_Waitframes(this, ghost, 24);
- }
- else if(attack==3){ //Shoot (Angular)
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY()), 150);
- EZB_Waitframes(this, ghost, 24);
- }
- else if(attack==4){ //Tri Shot (Directional)
- EZB_FiringAnim(this, ghost);
- for(i=-1; i<=1; i++){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, EZB_DirAngle(Ghost_Dir)+30*i, 250);
- }
- EZB_Waitframes(this, ghost, 24);
- }
- else if(attack==5){ //Tri Shot (Angular)
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- for(i=-1; i<=1; i++){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())+30*i, 250);
- }
- EZB_Waitframes(this, ghost, 24);
- }
- else if(attack==6){ //Stream (Directional)
- EZB_FiringAnim(this, ghost);
- angle = EZB_DirAngle(Ghost_Dir);
- EZB_Waitframes(this, ghost, 12);
- for(i=0; i<10; i++){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle, 350);
- EZB_Waitframes(this, ghost, 8);
- }
- EZB_Waitframes(this, ghost, 12);
- }
- else if(attack==7){ //Stream (Angular)
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
- EZB_Waitframes(this, ghost, 12);
- for(i=0; i<10; i++){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle, 350);
- EZB_Waitframes(this, ghost, 8);
- }
- EZB_Waitframes(this, ghost, 12);
- }
- else if(attack==8){ //Breath (Directional)
- EZB_FiringAnim(this, ghost);
- angle = EZB_DirAngle(Ghost_Dir);
- EZB_Waitframes(this, ghost, 24);
- for(i=0; i<24; i++){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle+Rand(-30, 30), 250);
- EZB_Waitframes(this, ghost, 4);
- }
- }
- else if(attack==9){ //Breath (Angular)
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
- EZB_Waitframes(this, ghost, 24);
- for(i=0; i<24; i++){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle+Rand(-30, 30), 250);
- EZB_Waitframes(this, ghost, 4);
- }
- }
- else if(attack==10){ //Sweep (Directional)
- EZB_FiringAnim(this, ghost);
- k = Choose(-1, 1);
- angle = EZB_DirAngle(Ghost_Dir)-45*k;
- for(i=0; i<18; i++){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle, 250);
- angle += k*5;
- EZB_Waitframes(this, ghost, 2);
- }
- }
- else if(attack==11){ //Sweep (Angular)
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- k = Choose(-1, 1);
- angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())-45*k;
- for(i=0; i<18; i++){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle, 250);
- angle += k*5;
- EZB_Waitframes(this, ghost, 2);
- }
- }
- else if(attack==12){ //Bullet Barrage
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())-45*k;
- for(i=0; i<3; i++){
- for(j=-4; j<=4; j+=2){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle+16*j, 150);
- }
- EZB_Waitframes(this, ghost, 16);
- for(j=-5; j<=5; j+=2){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle+16*j, 150);
- }
- EZB_Waitframes(this, ghost, 24);
- }
- EZB_Waitframes(this, ghost, 24);
- }
- else if(attack==13){ //Bullet swirl
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- k = Choose(-1, 1);
- angle = Rand(360);
- for(i=0; i<20; i++){
- for(j=0; j<5; j++){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle+72*j, 150);
- }
- angle += 4*k;
- EZB_Waitframes(this, ghost, 4);
- }
- EZB_Waitframes(this, ghost, 24);
- }
- else if(attack==14){ //Random bullet burst
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- for(i=0; i<40; i++){
- EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, Rand(360), 250);
- EZB_Waitframes(this, ghost, 2);
- }
- EZB_Waitframes(this, ghost, 24);
- }
- else if(attack==15){ //Laser
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
- for(i=0; i<30; i++){
- if(i%4<2){
- DrawLaser(4, CenterX(ghost), CenterY(ghost), 8, angle, C_EZB_LASER3);
- }
- EZB_Waitframe(this, ghost);
- }
- Game->PlaySound(SFX_EZB_LASER);
- for(i=0; i<20; i++){
- Laser3Color(4, CenterX(ghost), CenterY(ghost), 8, angle, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
- EZB_Waitframe(this, ghost);
- }
- }
- else if(attack==16){ //Big Laser
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
- for(i=0; i<60; i++){
- if(i%4<2){
- DrawLaser(4, CenterX(ghost), CenterY(ghost), 40, angle, C_EZB_LASER3);
- }
- EZB_Waitframe(this, ghost);
- }
- Game->PlaySound(SFX_EZB_LASER);
- for(i=0; i<40; i++){
- Laser3Color(4, CenterX(ghost), CenterY(ghost), 40, angle, ghost->WeaponDamage*2, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
- EZB_Waitframe(this, ghost);
- }
- }
- else if(attack==17){ //Laser Spread
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
- for(i=0; i<30; i++){
- for(j=-2; j<=2; j++){
- if(i%4<2){
- DrawLaser(4, CenterX(ghost), CenterY(ghost), 6, angle+30*j, C_EZB_LASER3);
- }
- }
- EZB_Waitframe(this, ghost);
- }
- Game->PlaySound(SFX_EZB_LASER);
- for(i=0; i<20; i++){
- for(j=-2; j<=2; j++){
- Laser3Color(4, CenterX(ghost), CenterY(ghost), 6, angle+30*j, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
- }
- EZB_Waitframe(this, ghost);
- }
- }
- else if(attack==18){ //Laser Spin
- EZB_FaceLink(this, ghost);
- EZB_FiringAnim(this, ghost);
- k = Choose(-1, 1);
- angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())+45;
- Game->PlaySound(SFX_EZB_LASER);
- for(i=0; i<30; i++){
- for(j=0; j<4; j++){
- Laser3Color(4, CenterX(ghost), CenterY(ghost), 6, angle+90*j, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
- }
- EZB_Waitframe(this, ghost);
- }
- for(i=0; i<30; i++){
- for(j=0; j<4; j++){
- Laser3Color(4, CenterX(ghost), CenterY(ghost), 6, angle+90*j, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
- }
- angle += k;
- EZB_Waitframe(this, ghost);
- }
- for(i=0; i<120; i++){
- for(j=0; j<4; j++){
- Laser3Color(4, CenterX(ghost), CenterY(ghost), 6, angle+90*j, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
- }
- angle += k*1.5;
- EZB_Waitframe(this, ghost);
- }
- for(i=0; i<30; i++){
- for(j=0; j<4; j++){
- Laser3Color(4, CenterX(ghost), CenterY(ghost), 6, angle+90*j, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
- }
- angle += k;
- EZB_Waitframe(this, ghost);
- }
- }
- Ghost_Data = combo;
- attackCooldown = ghost->Haltrate*10;
- if(movementStyle==4){ //Wall bounce
- angle = Rand(360);
- vX = VectorX(ghost->Step/100, angle);
- vY = VectorY(ghost->Step/100, angle);
- }
- }
- EZB_Waitframe(this, ghost);
- }
- }
- bool EZB_CanMoveAngle(int angle){
- int vx = VectorX(10, angle);
- int vy = VectorY(10, angle);
- if((vx<0&&!Ghost_CanMove(DIR_LEFT, 1, 0))||(vx>0&&!Ghost_CanMove(DIR_RIGHT, 1, 0)))
- return false;
- if((vy<0&&!Ghost_CanMove(DIR_UP, 1, 0))||(vy>0&&!Ghost_CanMove(DIR_DOWN, 1, 0)))
- return false;
- return true;
- }
- void EZB_FiringAnim(ffc this, npc ghost){
- int flags = ghost->Attributes[9];
- int combo = ghost->Attributes[10];
- if(flags&EZBF_8WAY)
- Ghost_Data = combo+8;
- else if(flags&EZBF_4WAY)
- Ghost_Data = combo+4;
- else
- Ghost_Data = combo+1;
- }
- void EZB_Trail(ffc this, npc ghost){
- int flags = ghost->Attributes[9];
- int tile = Game->ComboTile(Ghost_Data);
- if(flags&EZBF_4WAY||flags&EZBF_8WAY)
- tile = Game->ComboTile(Ghost_Data+Ghost_Dir);
- lweapon trail = CreateLWeaponAt(LW_SCRIPT10, ghost->X+ghost->DrawXOffset, ghost->Y+ghost->DrawYOffset);
- trail->Extend = 3;
- trail->TileWidth = ghost->TileWidth;
- trail->TileHeight = ghost->TileHeight;
- trail->DrawYOffset = 0;
- trail->CSet = this->CSet;
- trail->Tile = tile;
- trail->OriginalTile = tile;
- trail->DrawStyle = DS_PHANTOM;
- trail->DeadState = 8;
- }
- int EZB_DirAngle(int dir){
- if(dir==DIR_UP)
- return -90;
- else if(dir==DIR_DOWN)
- return 90;
- else if(dir==DIR_LEFT)
- return 180;
- else if(dir==DIR_LEFTUP)
- return -135;
- else if(dir==DIR_RIGHTUP)
- return -45;
- else if(dir==DIR_LEFTDOWN)
- return 135;
- else if(dir==DIR_RIGHTDOWN)
- return 45;
- else
- return 0;
- }
- eweapon EZB_Fire(ffc this, npc ghost, int x, int y, int angle, int step){
- int flags = ghost->Attributes[9];
- int type = WeaponTypeToID(ghost->Weapon);
- int wflags;
- if(flags&EZBF_UNBLOCKABLE)
- wflags |= EWF_UNBLOCKABLE;
- if(type==EW_BEAM||type==EW_ARROW||type==EW_MAGIC||type==EW_BOMB||type==EW_SBOMB)
- wflags |= EWF_ROTATE;
- int fireSFX = ghost->Attributes[7];
- int fireSPR = ghost->Attributes[8];
- int sfx = fireSFX;
- if(fireSFX<=0)
- sfx = -1;
- int spr = fireSPR;
- if(fireSPR<=0)
- spr = -1;
- eweapon e = FireEWeapon(type, x, y, DegtoRad(angle), step, ghost->WeaponDamage, spr, sfx, wflags);
- return e;
- }
- void EZB_Teleport(ffc this, npc ghost){
- int size = ghost->Attributes[6];
- int w = size&1111b;
- int h = (size>>4)&1111b;
- if(h==0)
- h = w;
- w = Clamp(w, 1, 4);
- h = Clamp(h, 1, 4);
- Game->PlaySound(SFX_EZB_TELEPORT);
- int tc;
- ghost->CollDetection = false;
- for(int i=0; i<16; i++){
- if(i%2==0)
- ghost->DrawYOffset = -1000;
- else
- ghost->DrawYOffset = -2;
- EZB_Waitframe(this, ghost);
- }
- ghost->DrawYOffset = -1000;
- tc = Rand(176);
- for(int i=0; i<352&&(!EZB_CanPlace(this, ghost, ComboX(tc), ComboY(tc))||Distance(ComboX(tc)+ghost->HitWidth/2, ComboY(tc)+ghost->HitHeight/2, CenterLinkX(), CenterLinkY())<((w+h)/2)*8+32); i++){
- if(i>=176)
- tc = i-176;
- else
- tc = Rand(176);
- }
- Ghost_X = ComboX(tc);
- Ghost_Y = ComboY(tc);
- EZB_Waitframe(this, ghost);
- EZB_FaceLink(this, ghost);
- for(int i=0; i<16; i++){
- if(i%2==0)
- ghost->DrawYOffset = -1000;
- else
- ghost->DrawYOffset = -2;
- EZB_Waitframe(this, ghost);
- }
- ghost->DrawYOffset = -2;
- ghost->CollDetection = true;
- }
- int EZB_AngleDir(ffc this, npc ghost, int angle){
- int flags = ghost->Attributes[9];
- if(flags&EZBF_8WAY)
- return AngleDir8(angle);
- else
- return AngleDir4(angle);
- }
- void EZB_FaceLink(ffc this, npc ghost){
- int flags = ghost->Attributes[9];
- if(flags&EZBF_8WAY)
- Ghost_Dir = AngleDir8(Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY()));
- else
- Ghost_Dir = AngleDir4(Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY()));
- }
- bool EZB_CanPlace(ffc this, npc ghost, int X, int Y){
- for(int x=ghost->HitXOffset; x<=ghost->HitXOffset+ghost->HitWidth-1; x=Min(x+8, ghost->HitXOffset+ghost->HitWidth-1)){
- for(int y=ghost->HitYOffset; y<=ghost->HitYOffset+ghost->HitHeight-1; y=Min(y+8, ghost->HitYOffset+ghost->HitHeight-1)){
- if(!Ghost_CanMovePixel(X+x, Y+y))
- return false;
- if(y==ghost->HitYOffset+ghost->HitHeight-1)
- break;
- }
- if(x==ghost->HitXOffset+ghost->HitWidth-1)
- break;
- }
- return true;
- }
- void EZB_Waitframes(ffc this, npc ghost, int frames){
- for(int i=0; i<frames; i++){
- EZB_Waitframe(this, ghost);
- }
- }
- void EZB_Waitframe(ffc this, npc ghost){
- int flags = ghost->Attributes[9];
- if(flags&EZBF_EXPLODEEATH)
- Ghost_Waitframe(this, ghost, 1, true);
- else
- Ghost_Waitframe(this, ghost);
- }
- }
- ffc script gbmold
- {
- void run(int enemyID)
- {
- npc ghost = Ghost_InitAutoGhost(this, enemyID);
- Ghost_SetFlag(GHF_FULL_TILE_MOVEMENT);
- Ghost_SetFlag(GHF_REDUCED_KNOCKBACK);
- npc segment[2];
- int Xtrack[160];
- int Ytrack[160];
- int vars [16] = {Xtrack,Ytrack};
- for(int i=0;i<2;i++)
- {
- segment[i] = CreateNPCAt(NPC_ENEMYFIRE,Ghost_X,Ghost_Y);
- Ghost_SetAllDefenses(segment[i],NPCDT_IGNORE);
- segment[i]->DrawYOffset = -1000;
- segment[i]->Damage= ghost->Damage;
- }
- for(int i=0; i<SizeOfArray(Xtrack); i++)
- {
- Xtrack[i] = Ghost_X;
- Ytrack[i] = Ghost_Y;
- }
- int angle = Rand(600);
- int turndir = Choose(-1,0,1);
- int turncounter = Choose(-1,0,1);
- ghost->DrawYOffset = -1000;
- while (true)
- {
- angle = WrapDegrees(angle+turndir*4);
- Ghost_Dir = AngleDir8(angle);
- Ghost_MoveAtAngle(angle, ghost->Step/100, 0);
- if(turncounter>0)
- turncounter--;
- else
- turndir = Choose(-1, 0, 1);
- int vx = VectorX(10, angle);
- int vy = VectorY(10, angle);
- if((vx<0&&!Ghost_CanMove(DIR_LEFT, 1, 0))||(vx>0&&!Ghost_CanMove(DIR_RIGHT, 1, 0))){
- vx = -vx;
- }
- if((vy<0&&!Ghost_CanMove(DIR_UP, 1, 0))||(vy>0&&!Ghost_CanMove(DIR_DOWN, 1, 0))){
- vy = -vy;
- }
- angle = Angle(0, 0, vx, vy);
- Mold_Waitframe(this, ghost, segment, vars);
- }
- Mold_Waitframe(this,ghost,segment,vars);
- }
- void Mold_Waitframe(ffc this, npc ghost,npc segment,int vars)
- {
- Mold_UpdateTrack(vars);
- Mold_Draw(this,ghost,segment,vars);
- if(!Ghost_Waitframe(this, ghost, false, false))
- {
- ghost->DrawYOffset = -2;
- Mold_UpdateTrack(vars);
- Mold_Draw(this, ghost, segment,vars);
- Ghost_Waitframe(this, ghost);
- }
- }
- void Mold_UpdateTrack(int vars)
- {
- int Xtrack=vars[0];
- int Ytrack=vars[1];
- for(int i=SizeOfArray(Xtrack)-1;i>=1;i--)
- {
- Xtrack[i] = Xtrack[i-1];
- Ytrack[i] = Ytrack[i-1];
- }
- Xtrack[0] = Ghost_X;
- Ytrack[0] = Ghost_Y;
- }
- void Mold_Draw(ffc this,npc ghost, npc segment, int vars)
- {
- int Xtrack=vars[0];
- int Ytrack=vars[1];
- int combo = ghost->Attributes[10];
- for (int i=1; i>=0; i--)
- {
- if(segment[i]->isValid())
- {
- if(ghost->HP<=0)
- {
- segment[i]->HP=-1000;
- }
- else
- {
- int spacing = 10;
- int x = Xtrack[spacing+spacing*i];
- int y = Ytrack[spacing+spacing*i];
- segment[i]->X = x;
- segment[i]->Y = y;
- Screen->FastCombo(2,x,y,combo+8+i,this->CSet,128);
- }
- }
- }
- //ghost->DrawYOffset = -1000;
- Screen->FastCombo(2,Ghost_X,Ghost_Y,combo+Ghost_Dir, this->CSet,128);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement