Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import "std.zh"
- import "string.zh"
- import "ghost.zh"
- // Used by otherscripts most likely
- const int COLOR_WHITE = 1;
- // Idle Settings
- const int DARKLINK_MIN_IDLE_TIME = 48;
- const int DARKLINK_MAX_IDLE_TIME = 96;
- // Rush Settings
- const int DARKLINK_MIN_ATTACK_FACTOR = .5; // Used with haltrate
- const int DARKLINK_MAX_ATTACK_FACTOR = 1.5; // Used with haltrate
- // Dodge Settings
- const int DARKLINK_DODGE_STEP = 0.8;
- // Jump Settings
- const float DARKLINK_JUMP_VELOCITY = 3.2; // Jump Velocity
- const float DARKLINK_JUMP_STEP = 1;
- // Attack settings
- const float DARKLINK_ATTACK_DISTANCE = 24.0; // Distance to Link's Center to DarkLink's Center
- const int DARKLINK_CAN_SLASH = 1; //includes spin attacks
- const int DARKLINK_SWORD_FLIP_FIX = 1; //set this to one if Links down facing sword is flipped horizontally and not just veritcally.
- const int DARKLINK_CAN_SLASH_FLIP_FIX = 0; //set this to one if Links right slash tile is flipped
- // Charge Settings
- const float DARKLINK_CHARGE_STEP = 1;
- const int DARKLINK_SWORDCHARGEFRAME= 20;
- const int DARKLINK_SPIN_CHARGE_TIME = 64;
- const int DARKLINK_HSPIN_CHARGE_TIME = 192;
- // Spin Attack Settings
- const float DARKLINK_SPIN_DAMAGE_MULTIPLIER = 2;
- const int DARKLINK_SPIN_COUNT = 1;
- // Hurricane Spin settings
- const float DARKLINK_HSPIN_DAMAGE_MULTIPLIER = 2;
- const int DARKLINK_HSPIN_COUNT = 20;
- // Quake Thrust settings
- const float DARKLINK_QTHRUST_DAMAGE_MULTIPLIER = 2;
- const int DARKLINK_QTHRUST_SPEED = 8;
- const int DARKLINK_QTHRUST_MIN_TIME = 240;
- const int DARKLINK_QTHRUST_MAX_TIME = 320;
- const int DARKLINK_QTHRUST_QUAKE_TIME = 90; // Shake the screen for this amount
- // Debris Settings
- const int DARKLINK_EW_DEBRIS = 31;
- const int DARKLINK_MIN_DEBRIS = 8;
- const int DARKLINK_MAX_DEBRIS = 12;
- const int DARKLINK_MIN_DEBRIS_STEP = 100;
- const int DARKLINK_MAX_DEBRIS_STEP = 200;
- const float DARKLINK_MIN_DEBRIS_VEL = 1.5;
- const float DARKLINK_MAX_DEBRIS_VEL = 2.5;
- // Default settings (can be overridden by attributes)
- //const int DARKLINK_DEFAULT_SIZE = 1; // 1, 2, or 3 "1x1, 1x2, 2x2 respectfully"
- const int DARKLINK_DEFAULT_STUN_TIME = 90;
- const int DARKLINK_DEFAULT_DEBRIS_DAMAGE = 16;
- const int DARKLINK_DEFAULT_DEBRIS_SPRITE = 18;
- // npc->Attributes[] indices
- //const int DARKLINK_ATTR_SIZE = 0;
- const int DARKLINK_ATTR_FLAGS = 1;
- const int DARKLINK_ATTR_STUN_TIME = 2;
- const int DARKLINK_ATTR_SFX_JUMP = 3;
- const int DARKLINK_ATTR_SFX_FALL = 4;
- const int DARKLINK_ATTR_SFX_QTHRUST = 5;
- const int DARKLINK_ATTR_DEBRIS_DAMAGE = 6;
- const int DARKLINK_ATTR_DEBRIS_SPRITE = 7;
- const int DARKLINK_ATTR_SWORD_SPRITE = 8; // You must provide this on your own.
- const int DARKLINK_ATTR_DEATH_TYPE = 9;
- // ffc->Misc[] indices
- const int DARKLINK_IDX_BASE_COMBO = 0;
- const int DARKLINK_IDX_KNOCKBACK = 1;
- const int DARKLINK_IDX_LINK_STUN_TIME = 2;
- // Combo offsets "4 combos each facing up down left right, they ignore direction if negative, and can share the same value if desired"
- const int DARKLINK_CMB_IDLE = 0;
- const int DARKLINK_CMB_RUSH = 1;
- const int DARKLINK_CMB_DODGE = 2;
- const int DARKLINK_CMB_JUMP = 3;
- const int DARKLINK_CMB_CHARGE = 4;
- const int DARKLINK_CMB_SLASH = 5;
- const int DARKLINK_CMB_STAB = 6;
- const int DARKLINK_CMB_SPIN = 7; // Both this and below should not be animated it is done manually and takes 4 or 8 combos depending if you enable DARKLINK_CAN_SLASH
- const int DARKLINK_CMB_HSPIN = 7; // HSpin should use the same combos as spin attack unless you desire otherwise.
- const int DARKLINK_CMB_QTHRUST = 9;
- // Flags
- const int DARKLINK_FLAG_FREEZABLE = 00000001b; // 1
- const int DARKLINK_FLAG_NO_HSPIN = 00000010b; // 2
- const int DARKLINK_FLAG_NO_QTHRUST = 00000100b; // 4
- const int DARKLINK_FLAG_STUN_LINK = 00000100b; // 8
- const int DARKLINK_FLAG_LAUNCH_DEBRIS = 00001000b; // 16
- const int DARKLINK_FLAG_DROP_OBJECTS = 00010000b; // 32
- const int DARKLINK_FLAG_SHIELDED = 01000000b; // 64
- const int DARKLINK_FLAG_INTRO = 10000000b; // 128
- ffc script Darklink
- {
- void run(int enemyID)
- {
- npc ghost=Ghost_InitAutoGhost(this, enemyID);
- if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_FREEZABLE)!=0)
- {
- Ghost_SetFlag(GHF_STUN);
- Ghost_SetFlag(GHF_CLOCK);
- }
- this->Misc[DARKLINK_IDX_BASE_COMBO]=Ghost_Data;
- // int defenses[18];
- // if(DARKLINK_SHIELDED)
- // {
- // Ghost_StoreDefenses(ghost, defenses);
- // Ghost_SetAllDefenses(ghost, NPCDT_BLOCK);
- // }
- if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_INTRO)!=0)
- DoIntro(this, ghost);
- else if(Ghost_Z==0)
- Ghost_SpawnAnimationPuff(this, ghost);
- else // Dropping from the ceiling?
- {
- while(Ghost_Z>0)
- DLWaitframe(this, ghost);
- }
- int superattack;
- int spinchance=1;
- int hspinchance=-1;
- int qthrustchance=-1;
- int i;
- while(true) //Behavior it self
- {
- //Stand there like an idiot
- Idle(this,ghost);
- //Rush,Attack,Dodge loop
- int i;
- if(i==0)
- i=1;
- for(;i>0; i--)
- {
- Ghost_SetFlag(GHF_SET_DIRECTION);
- Rush(this,ghost);
- if(Attack(this,ghost))
- Dodge(this, ghost);
- else
- Jump(this,ghost);
- }
- //Super Attack!
- if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_NO_HSPIN)==0)
- {
- if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_NO_QTHRUST)==0)
- {
- spinchance=2;
- hspinchance=4;
- qthrustchance=6;
- }
- else
- {
- spinchance=3;
- hspinchance=6;
- }
- }
- if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_NO_QTHRUST)==0)
- {
- if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_NO_HSPIN)!=0)
- {
- spinchance=3;
- qthrustchance=6;
- }
- }
- superattack=Rand(6);
- if(superattack<spinchance)
- {
- eweapon sword=Charge(this,ghost,DARKLINK_SPIN_CHARGE_TIME);
- SpinAttack(this,ghost,sword,false);
- }
- else if(superattack<hspinchance)
- {
- eweapon sword=Charge(this,ghost,DARKLINK_HSPIN_CHARGE_TIME);
- SpinAttack(this,ghost,sword,true);
- }
- else if(superattack<qthrustchance)
- {
- Ghost_Dir=DIR_DOWN;
- QuakeThrust(this,ghost);
- }
- }
- }
- void Idle(ffc this, npc ghost)
- {
- Ghost_Data=GetComboOffset(this, DARKLINK_CMB_IDLE);
- for(int i=Rand(DARKLINK_MIN_IDLE_TIME,DARKLINK_MAX_IDLE_TIME); i>0; i--)
- DLWaitframe(this,ghost);
- }
- void Rush(ffc this, npc ghost)
- {
- Ghost_Data=GetComboOffset(this, DARKLINK_CMB_RUSH);
- //Rush at Link
- do
- {
- Ghost_MoveTowardLink(ghost->Step/100,3);
- DLWaitframe(this,ghost);
- } while(DLDistanceTo(CenterLinkX(),CenterLinkY())>DARKLINK_ATTACK_DISTANCE);
- }
- bool Attack(ffc this, npc ghost)
- {
- eweapon sword = FireEWeapon(EW_SCRIPT1, Ghost_X, Ghost_Y, 0, 0, ghost->WeaponDamage, ghost->Attributes[DARKLINK_ATTR_SWORD_SPRITE], SFX_SWORD, EWF_NO_COLLISION);
- int dir=Ghost_Dir;
- for(int i=1; i <= 14; i++)
- {
- //set combo
- if(DARKLINK_CAN_SLASH&&i<6)
- Ghost_Data=GetComboOffset(this, DARKLINK_CMB_SLASH);
- else
- Ghost_Data=GetComboOffset(this, DARKLINK_CMB_STAB);
- //Updating the sword itself is handled separately
- sword=UpdateSword(sword,0,i,0,this,ghost);
- DLSwordWaitframe(this,ghost,sword);
- if(Ghost_GotHit())
- break;
- }
- if(sword->isValid())
- sword->DeadState=WDS_DEAD;
- return Ghost_GotHit();
- }
- void Dodge(ffc this, npc ghost)
- {
- Ghost_Data=GetComboOffset(this, DARKLINK_CMB_DODGE);
- float linkangle=ArcTan(DLCenterX()-CenterLinkX(),DLCenterY()-CenterLinkY());
- Ghost_Jump=2.8;
- Game->PlaySound(ghost->Attributes[DARKLINK_ATTR_SFX_JUMP]);
- while(Ghost_Z>0 || Ghost_Jump>0)
- {
- Ghost_MoveAtAngle(linkangle,DARKLINK_JUMP_STEP*(ghost->Step/100),3);
- Ghost_ForceDir(OppositeDir(RadianAngleDir4(linkangle)));
- }
- }
- void Jump(ffc this, npc ghost)
- {
- int dir=JumpDirection();
- if(dir==-1)
- {
- Dodge(this,ghost); //this happens vary rarely
- return;
- }
- Ghost_Jump=DARKLINK_JUMP_VELOCITY;
- Game->PlaySound(ghost->Attributes[DARKLINK_ATTR_SFX_JUMP]);
- while(Ghost_Z>0 || Ghost_Jump>0)
- {
- Ghost_Move(dir,DARKLINK_JUMP_STEP*(ghost->Step/100),3);
- Ghost_ForceDir(OppositeDir(dir));
- }
- }
- eweapon Charge(ffc this, npc ghost, int time)
- {
- eweapon sword = FireEWeapon(EW_SCRIPT1, Ghost_X, Ghost_Y, 0, 0, ghost->WeaponDamage, ghost->Attributes[DARKLINK_ATTR_SWORD_SPRITE], SFX_SWORD, EWF_NO_COLLISION);
- int dir=Ghost_Dir;
- int attackclk=1;
- for(; attackclk <= 14; attackclk++)
- {
- //set combo
- if(DARKLINK_CAN_SLASH&&attackclk<6)
- Ghost_Data=GetComboOffset(this, DARKLINK_CMB_SLASH);
- else
- Ghost_Data=GetComboOffset(this, DARKLINK_CMB_STAB);
- //Updating the sword itself is handled separately
- sword=UpdateSword(sword,attackclk,0,0,this,ghost);
- DLSwordWaitframe(this,ghost,sword);
- }
- for(int charging; charging < time; charging++)
- {
- Ghost_Data=GetComboOffset(this, DARKLINK_CMB_CHARGE);
- Ghost_MoveTowardLink(ghost->Step/100,3);
- if(attackclk<DARKLINK_SWORDCHARGEFRAME) attackclk++;
- sword=UpdateSword(sword,attackclk,charging,0,this,ghost);
- DLSwordWaitframe(this,ghost,sword);
- }
- return sword;
- }
- void SpinAttack(ffc this, npc ghost, eweapon sword, bool hurricane)
- {
- int attackclk=1;
- int spins = Cond(hurricane,(DARKLINK_HSPIN_COUNT*4)-3,(DARKLINK_SPIN_COUNT*4)+1);
- int charging = Cond(hurricane,DARKLINK_HSPIN_CHARGE_TIME, DARKLINK_SPIN_CHARGE_TIME);
- // Faster if spinning.
- for(;spins>0;spins--)
- {
- attackclk+=Cond(hurricane,4,2);
- Ghost_Data=GetComboOffset(this,Cond(hurricane,DARKLINK_CMB_SPIN,DARKLINK_CMB_HSPIN));
- if(DARKLINK_CAN_SLASH && attackclk>=7 && attackclk<11)
- Ghost_Data+=4;
- if(hurricane) Ghost_MoveTowardLink(ghost->Step/100,3);
- sword=UpdateSword(sword,charging,attackclk,spins,this,ghost);
- attackclk=Spin(spins,attackclk);
- DLSwordWaitframe(this,ghost,sword);
- }
- sword->DeadState=WDS_DEAD;
- }
- int Spin(int spins, int attackclk)
- {
- if(spins>1)
- {
- if(spins%5==0)
- {
- attackclk=1;
- if(Ghost_Dir==DIR_UP)
- Ghost_Dir=DIR_LEFT;
- else if(Ghost_Dir==DIR_DOWN)
- Ghost_Dir=DIR_UP;
- else if(Ghost_Dir==DIR_DOWN)
- Ghost_Dir=DIR_RIGHT;
- else if(Ghost_Dir==DIR_LEFT)
- Ghost_Dir=DIR_DOWN;
- else
- spins=0;
- }
- }
- return attackclk;
- }
- void QuakeThrust(ffc this, npc ghost)
- {
- //Set Overlay and No Fall
- this->Flags[FFCF_OVERLAY];
- Ghost_SetFlag(GHF_NO_FALL);
- int dDamage=ghost->Damage;
- //Jump
- Game->PlaySound(ghost->Attributes[DARKLINK_ATTR_SFX_JUMP]);
- while(Ghost_Z<176)
- {
- Ghost_Data=GetComboOffset(this,DARKLINK_CMB_JUMP);
- Ghost_Z+=DARKLINK_QTHRUST_SPEED;
- DLWaitframe(this,ghost);
- }
- //Seek Link
- for(int i = Rand(DARKLINK_QTHRUST_MIN_TIME,DARKLINK_QTHRUST_MAX_TIME);i>0;i--)
- {
- Ghost_MoveTowardLink(ghost->Step/100,3);
- DLWaitframe(this,ghost);
- }
- //Fall
- Game->PlaySound(ghost->Attributes[DARKLINK_ATTR_SFX_FALL]);
- while(Ghost_Z>0)
- {
- Ghost_Data=GetComboOffset(this,DARKLINK_CMB_QTHRUST);
- Ghost_Z-=DARKLINK_QTHRUST_SPEED;
- DLWaitframe(this,ghost);
- }
- //Darklink's Jam
- Game->PlaySound(ghost->Attributes[DARKLINK_ATTR_SFX_QTHRUST]);
- Screen->Quake=DARKLINK_QTHRUST_QUAKE_TIME;
- if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_STUN_LINK) && Link->Z==0 && !LinkCollision(ghost)) //be nice! no stun on collision with link.
- this->Misc[DARKLINK_IDX_LINK_STUN_TIME]=Ghost_GetAttribute(ghost,DARKLINK_ATTR_STUN_TIME, DARKLINK_DEFAULT_STUN_TIME);
- LaunchDebris(ghost);
- DropObjects(ghost);
- DLWaitframe(this,ghost);
- ghost->Damage=dDamage;
- this->Flags[FFCF_OVERLAY]=false;
- Ghost_UnsetFlag(GHF_NO_FALL);
- return;
- }
- void DoIntro(ffc this, npc ghost)
- {
- Ghost_Data=GH_INVISIBLE_COMBO;
- //Flash Screen
- for(int i; i<60; i++) //2 seconds
- {
- Screen->Rectangle(6,0,0,256,176,COLOR_WHITE,-1, 0,0,0,true,128);
- for(int j; j < 2; j++)
- {
- NoAction();
- Ghost_WaitframeLight(this,ghost);
- }
- }
- Ghost_Data=ghost->Attributes[11]+GetComboOffset(this, DARKLINK_CMB_DODGE);
- Ghost_X=Link->X;
- Ghost_Y=Link->Y;
- ghost->CollDetection=false;
- Ghost_Dir=OppositeDir(Link->Dir);
- Ghost_Jump=DARKLINK_JUMP_VELOCITY*.75;
- while(Ghost_Jump>0 || Ghost_Z>0)
- {
- NoAction();
- Ghost_ForceDir(OppositeDir(Link->Dir));
- Ghost_Move(OppositeDir(Ghost_Dir),(DARKLINK_JUMP_STEP*ghost->Step)/100,3);
- DLWaitframe(this,ghost);
- }
- ghost->CollDetection=true;
- }
- void DLWaitframe(ffc this, npc ghost)
- {
- if(this->Misc[DARKLINK_IDX_LINK_STUN_TIME]>0)
- {
- NoAction();
- this->Misc[DARKLINK_IDX_LINK_STUN_TIME]--;
- }
- if((this->Misc[DARKLINK_IDX_KNOCKBACK]%1)/10000)
- {
- int counter=(this->Misc[DARKLINK_IDX_KNOCKBACK]%1)/10000;
- counter;
- Ghost_MoveAtAngle(this->Misc[DARKLINK_IDX_KNOCKBACK]>>0,2,3);
- }
- bool noDeathAnim=(ghost->Attributes[DARKLINK_ATTR_DEATH_TYPE]==0);
- if(!Ghost_Waitframe(this, ghost, noDeathAnim, noDeathAnim))
- {
- if(ghost->Attributes[DARKLINK_ATTR_DEATH_TYPE]!=-1)
- Ghost_DeathAnimation(this, ghost, ghost->Attributes[DARKLINK_ATTR_DEATH_TYPE]);
- else
- Dissolve(this, ghost, false);
- Quit();
- }
- }
- void DLSwordWaitframe(ffc this, npc ghost, eweapon sword)
- {
- if(this->Misc[DARKLINK_IDX_LINK_STUN_TIME]>0)
- {
- NoAction();
- this->Misc[DARKLINK_IDX_LINK_STUN_TIME]--;
- }
- if((this->Misc[DARKLINK_IDX_KNOCKBACK]%1)/10000)
- {
- int counter=((this->Misc[DARKLINK_IDX_KNOCKBACK]%1)/10000)-1;
- float oldx=Ghost_X;
- float oldy=Ghost_Y;
- Ghost_MoveAtAngle(this->Misc[DARKLINK_IDX_KNOCKBACK]>>0,1,3);
- sword->X+=oldx-Ghost_X;
- sword->Y+=oldy-Ghost_Y;
- this->Misc[DARKLINK_IDX_KNOCKBACK]=Floor(this->Misc[DARKLINK_IDX_KNOCKBACK])+counter;
- }
- bool noDeathAnim=(ghost->Attributes[DARKLINK_ATTR_DEATH_TYPE]==0);
- if(!Ghost_Waitframe(this, ghost, noDeathAnim, noDeathAnim))
- {
- sword->DeadState=WDS_DEAD;
- if(ghost->Attributes[DARKLINK_ATTR_DEATH_TYPE]!=-1)
- Ghost_DeathAnimation(this, ghost, ghost->Attributes[DARKLINK_ATTR_DEATH_TYPE]);
- else
- Dissolve(this, ghost, false);
- Quit();
- }
- }
- void Dissolve(ffc this, npc ghost, bool flash)
- {
- int baseX=Ghost_X+ghost->DrawXOffset;
- int baseY=(Ghost_Y+ghost->DrawYOffset)-(Ghost_Z+ghost->DrawZOffset);
- __DeathAnimStart(this, ghost);
- __DeathAnimSFX(ghost->ID, ghost->X);
- if(flash)
- __Ghost_FlashCounter=10000;
- else
- __Ghost_FlashCounter=0;
- ghost->DrawXOffset=1000;
- int x;
- int y;
- int layer=Cond((Screen->Flags[SF_VIEW]&10000b)!=0,1,2);
- bool pixel[256];
- //16 pixels every 16 frames
- for(int i; i < 16; i++)
- {
- Screen->SetRenderTarget(RT_BITMAP6);
- Screen->FastCombo(0,baseX,baseY,Ghost_Data+Ghost_Dir,ghost->CSet,128);
- for(int j; j < 16; j++)
- {
- while(true) //ack...
- {
- x=Rand(16);
- y=Rand(16);
- if(!pixel[x+(y*16)])
- break;
- else // o_O
- {
- x=Rand(16);
- if(!pixel[x+(y*16)])
- break;
- y=Rand(16);
- if(!pixel[x+(y*16)])
- break;
- }
- }
- pixel[x+(y*16)]=true;
- Screen->PutPixel(0,baseX+x,baseY+y,0,0,0,0,128);
- }
- Screen->SetRenderTarget(RT_SCREEN);
- for(int j; j<16; j++)
- {
- Screen->DrawBitmap(layer, RT_BITMAP6, baseX, baseY, 16, 16, baseX, baseY, 16, 16, 0, true);
- Ghost_WaitframeLight(this,ghost);
- }
- }
- __DeathAnimEnd(this, ghost);
- }
- int JumpDirection()
- {
- int top = Link->Y;
- int bottom = Link->Y+15;
- int left = Link->X;
- int right = Link->X+15;
- int b=32; //2/3 of this is used for the y axis
- if(Abs(DLCenterY()-CenterLinkY())<Abs(DLCenterX()-CenterLinkX())) // Horizontal Jump
- {
- if(left<32+b || right > 224-b) // Too close jump away
- return RadianAngleDir4(ArcTan(DLCenterX()-CenterLinkX(),0));
- else // Too far jump towards
- return RadianAngleDir4(ArcTan(CenterLinkX()-DLCenterX(),0));
- }
- else if(Abs(DLCenterX()-CenterLinkX())>Abs(DLCenterX()-CenterLinkX()))
- {
- if(left<32+b || right > 224-b) // Too close jump away
- return RadianAngleDir4(ArcTan(0,DLCenterY()-CenterLinkY()));
- else // Too far jump towards
- return RadianAngleDir4(ArcTan(0,CenterLinkY()-DLCenterY()));
- }
- else //rare occasion just dodge return -1 and Dodge as a result.
- return -1;
- }
- eweapon UpdateSword(eweapon sword, int attackclk, int charging, int spins, ffc this, npc ghost)
- {
- if(attackclk>4||DARKLINK_CAN_SLASH)
- {
- if(!sword->isValid()) // Create one if sword nonexistant
- sword=FireEWeapon(EW_SCRIPT1, Ghost_X, Ghost_Y, 0, 0, ghost->WeaponDamage, ghost->Attributes[DARKLINK_ATTR_SWORD_SPRITE], SFX_SWORD, EWF_NO_COLLISION);
- sword->DeadState=WDS_ALIVE;
- PositionSword(sword,attackclk,charging,spins);
- }
- if(!charging && !spins) // remove the sword
- sword->DeadState=WDS_DEAD;
- else
- { //check for collision
- lweapon linksword=LoadLWeaponOf(LW_SWORD);
- if(!((this->Misc[DARKLINK_IDX_KNOCKBACK]%1)*10000))
- {
- if(Collision(sword,linksword))
- {
- this->Misc[DARKLINK_IDX_KNOCKBACK]=Angle(linksword->X,linksword->Y,sword->X,sword->Y)>>0 + (32/10000);
- Game->PlaySound(SFX_CLINK);
- }
- }
- if(LinkCollision(sword) && Link->CollDetection)
- {
- if(charging>=DARKLINK_HSPIN_CHARGE_TIME) Link->HP-((ghost->WeaponDamage*4)*DARKLINK_HSPIN_DAMAGE_MULTIPLIER);
- else if(charging) Link->HP-((ghost->WeaponDamage*4)*DARKLINK_SPIN_DAMAGE_MULTIPLIER);
- else Link->HP-ghost->WeaponDamage*4;
- Link->Action=LA_GOTHURTLAND;
- Link->HitDir=RadianAngleDir4(ArcTan(Link->X-sword->X,Link->Y-sword->Y));
- Game->PlaySound(SFX_OUCH);
- }
- }
- return sword;
- }
- void PositionSword(eweapon w, int attackclk, int charging, int spins)
- {
- int wx=1;
- int wy=1;
- int t=w->OriginalTile;
- int f=0;
- if(Ghost_Dir==DIR_UP)
- {
- wx=-1;
- wy=-12;
- if(DARKLINK_CAN_SLASH && !charging)
- {
- if(attackclk>10) //extended stab
- wy-=2;
- if(attackclk>=14) //retracting stab
- wy+=2;
- }
- else
- {
- if(attackclk>=DARKLINK_SWORDCHARGEFRAME)
- wy+=4;
- else if(attackclk==13)
- wy+=4;
- else if(attackclk==14)
- wy+=8;
- }
- }
- else if(Ghost_Dir==DIR_DOWN)
- {
- f=Cond(DARKLINK_SWORD_FLIP_FIX!=0,3,2);
- wy=11;
- if(DARKLINK_CAN_SLASH && !charging)
- {
- if(attackclk>10) //extended stab
- wy+=2;
- if(attackclk>=14) //retracting stab
- wy-=2;
- }
- else
- {
- if(attackclk==DARKLINK_SWORDCHARGEFRAME)
- wy-=2;
- else if(attackclk==13)
- wy-=4;
- else if(attackclk==14)
- wy-=8;
- }
- }
- else if(Ghost_Dir==DIR_LEFT)
- {
- f=1;
- wx=-11;
- t++;
- if(DARKLINK_CAN_SLASH && !charging)
- {
- if(attackclk>10) //extended stab
- wx-=7;
- if(attackclk>=14) //retracting stab
- wx+=7;
- }
- else
- {
- if(attackclk==DARKLINK_SWORDCHARGEFRAME)
- wx+=2;
- else if(attackclk==13)
- wx+=4;
- else if(attackclk==14)
- wx+=8;
- }
- }
- else if(Ghost_Dir==DIR_RIGHT)
- {
- wx=11;
- t++;
- if(DARKLINK_CAN_SLASH && !charging)
- {
- if(attackclk>10) //extended stab
- wx+=7;
- if(attackclk>=14) //retracting stab
- wx-=7;
- }
- else
- {
- if(attackclk==DARKLINK_SWORDCHARGEFRAME)
- wx-=2;
- else if(attackclk==13)
- wx-=4;
- else if(attackclk==14)
- wx-=8;
- }
- }
- if(DARKLINK_CAN_SLASH && attackclk<11)
- {
- int t2=t+2; //slashing tiles
- if(Ghost_Dir==DIR_UP)
- {
- wx=15;
- wy=-3;
- t++;
- f=0; //starts pointing right
- if(attackclk>=7)
- {
- wy-=9;
- wx-=3;
- t=t2;
- f=0;
- }
- }
- else if(Ghost_Dir==DIR_DOWN)
- {
- wx=-13;
- wy=-1;
- t++;
- f=1; //starts pointing left
- if(attackclk>=7)
- {
- wy+=15;
- wx+=2;
- t=t2;
- t++;
- f=0;
- }
- }
- else if(Ghost_Dir==DIR_LEFT)
- {
- wx=3;
- wy=-15;
- t--;
- f=0; //starts pointing up
- if(attackclk>=7)
- {
- wx-=15;
- wy+=3;
- t=t2;
- t+=2;
- f=0;
- }
- }
- if(Ghost_Dir==DIR_RIGHT)
- {
- t--;
- if(spins>0 || DARKLINK_SWORD_FLIP_FIX)
- {
- wx=1;
- wy=13;
- f=2;
- }
- else
- {
- wx=3;
- wy=-15;
- f=0;
- }
- if(attackclk>=7)
- {
- wx+=15;
- t=t2;
- if(spins>0 || DARKLINK_CAN_SLASH_FLIP_FIX)
- {
- wx-=1;
- wy-=2;
- }
- else
- {
- t+=3;
- f=0;
- wy+=3;
- }
- }
- }
- }
- w->X = Ghost_X+wx;
- w->Y = Ghost_Y+wy;;
- w->Tile = t;
- w->Flip = f;
- w->Dir = Ghost_Dir;
- }
- int DLCenterX()
- {
- Ghost_X+(Ghost_TileWidth*8);
- }
- int DLCenterY()
- {
- Ghost_Y+(Ghost_TileHeight*8);
- }
- int DLDistanceTo(float dx, float dy)
- {
- Distance(DLCenterX(),DLCenterY(),dx,dy);
- }
- int GetComboOffset(ffc this, int cmb)
- {
- if(cmb<0)
- return this->Misc[DARKLINK_IDX_BASE_COMBO]+(cmb*4);
- else
- return this->Misc[DARKLINK_IDX_BASE_COMBO]+(cmb*4)+Ghost_Dir;
- }
- void LaunchDebris(npc ghost)
- {
- if((ghost->Attributes[DARKLINK_ATTR_FLAGS] & DARKLINK_FLAG_LAUNCH_DEBRIS)==0)
- return;
- int sprite=Ghost_GetAttribute(ghost,DARKLINK_ATTR_DEBRIS_SPRITE,DARKLINK_DEFAULT_DEBRIS_SPRITE);
- int damage=Ghost_GetAttribute(ghost,DARKLINK_ATTR_DEBRIS_DAMAGE,DARKLINK_DEFAULT_DEBRIS_DAMAGE);
- int count=Rand(DARKLINK_MIN_DEBRIS, DARKLINK_MAX_DEBRIS);
- float angle;
- eweapon debris;
- for(;count>0;count--)
- {
- angle=Randf(PI2);
- debris=FireEWeapon(DARKLINK_EW_DEBRIS, DLCenterX()-8+8*RadianCos(angle), DLCenterY()-8+8*RadianSin(angle), angle,
- Rand(DARKLINK_MIN_DEBRIS_STEP, DARKLINK_MAX_DEBRIS_STEP), damage, sprite, 0, EWF_SHADOW|EWF_UNBLOCKABLE|EWF_FAKE_Z);
- SetEWeaponMovement(debris,EWM_THROW,Randf(DARKLINK_MIN_DEBRIS_VEL, DARKLINK_MAX_DEBRIS_VEL),EWMF_DIE);
- SetEWeaponDeathEffect(debris, EWD_VANISH, 0);
- }
- }
- void DropObjects(npc ghost)
- {
- if((ghost->Attributes[DARKLINK_ATTR_FLAGS] & DARKLINK_FLAG_DROP_OBJECTS)==0)
- return;
- int sprite=Ghost_GetAttribute(ghost,DARKLINK_ATTR_DEBRIS_SPRITE,DARKLINK_DEFAULT_DEBRIS_SPRITE);
- int damage=Ghost_GetAttribute(ghost,DARKLINK_ATTR_DEBRIS_DAMAGE,DARKLINK_DEFAULT_DEBRIS_DAMAGE);
- int count=Rand(DARKLINK_MIN_DEBRIS, DARKLINK_MAX_DEBRIS);
- eweapon debris;
- for(;count>0; count--)
- {
- debris=FireEWeapon(DARKLINK_EW_DEBRIS, Rand(16, 224), Rand(16, 144),0, 0, damage, sprite, 0, EWF_SHADOW|EWF_UNBLOCKABLE|EWF_FAKE_Z);
- SetEWeaponMovement(debris, EWM_FALL, Rand(160, 224), EWMF_DIE);
- SetEWeaponDeathEffect(debris, EWD_VANISH, 0);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement