PDA

View Full Version : Ball and Chain Item



Joe123
04-15-2009, 06:17 PM
Example Quest (http://zc.celestialrealm.net/scripts/9_BallandChainItemex.qst)


const int WSP_BALL = 45; //weapon/misc sprite for you ball head
const int T_CHAIN = 58; //chain-link sprite
const int SFX_BALL = 3; //sound effect for when the ball is thrown
const int CF_BALLCHAIN = 98; //'ball->next' flag
int BallDamage = 4; //damage dealt by ball
int BallSpeed = 6; //speed of spinning
bool BallCanMove = true; //true if Link can move whilst spinning the ball

int UseBall;
int BallCounter;
int BallRadius;
int LastHP;
int StoreInput;
void StoreInputs(){
if(Link->InputA && !Link->InputB) StoreInput = 1;
else if(Link->InputB && !Link->InputA) StoreInput = 2;
else if(Link->InputB && Link->InputA) StoreInput = 3;
else StoreInput = 0;
}
bool CheckInputs(){
return (((StoreInput&1) != 0 && Link->InputA) || ((StoreInput&2) != 0 && Link->InputB));
}

void NoAction(){
Link->InputUp = false; Link->InputDown = false;
Link->InputLeft = false; Link->InputRight = false;
Link->InputR = false; Link->InputL = false;
Link->InputA = false; Link->InputB = false;
}

bool ComboFI(int loc,int combotype){
if(Screen->ComboF[loc] == combotype
|| Screen->ComboI[loc] == combotype) return true;
}

global script Slot2{
void run(){
UseBall = 0;
while(true){
BallAndChain();
Waitframe();
}
}
void BallAndChain(){
if(UseBall == 0) return;
else if(UseBall < 25) ThrowBall();
else SpinBall();
LastHP = Link->HP;
}
void ThrowBall(){
lweapon Ball = FindBall();
if(LastHP < Link->HP){
Ball->DeadState = WDS_DEAD;
UseBall = 0;
return;
}
if(UseBall < 10){
int x = Link->X; int y = Link->Y;
if(Link->Dir == DIR_UP || Link->Dir == DIR_DOWN){ x += Link->Dir*16-8; y -= Link->Dir*32-16; }
else{ y += 8; x -= (Link->Dir-2)*32-16; }
Ball->X = x; Ball->Y = y;
}else if(UseBall < 15){
PlaceBall(Ball);
BallRadius += 8;
}else if(UseBall == 15) Game->PlaySound(SFX_BALL);
else PlaceBall(Ball);

UseBall++;
NoAction();
}
void SpinBall(){
lweapon Ball = FindBall();
if(LastHP < Link->HP || !CheckInputs()){
Ball->DeadState = WDS_DEAD;
UseBall = 0;
return;
}
PlaceBall(Ball);
BallCombo(Ball);

BallCounter = (BallCounter+BallSpeed)%360;
if(!BallCanMove) NoAction();
}
lweapon FindBall(){
lweapon l;
for(int i=1;i<=Screen->NumLWeapons();i++){
l = Screen->LoadLWeapon(i);
if(l->ID == LW_SCRIPT1) return l;
}
l = Screen->CreateLWeapon(LW_SCRIPT1);
l->Damage = BallDamage;
l->UseSprite(WSP_BALL);
return l;
}
void PlaceBall(lweapon Ball){
Ball->X = Link->X+BallRadius*Cos(BallCounter);
Ball->Y = Link->Y+BallRadius*Sin(BallCounter);
for(int i=4;i>0;i--)
Screen->DrawTile(2,Link->X+(40*(i/5))*Cos(BallCounter),Link->Y+(40*(i/5))*Sin(BallCounter),T_CHAIN,1,1,8,1,0,0,0,0,true, 128);
}
void BallCombo(lweapon Ball){
int loc = ComboAt(Ball->X,Ball->Y);
if(ComboFI(loc,CF_BALLCHAIN)){
Screen->ComboD[loc]++;
if(Screen->ComboF[loc] == CF_BALLCHAIN) Screen->ComboF[loc] = 0;
Game->PlaySound(SFX_BALL);
}
}
}

item script BallAndChain{
void run(){
if(UseBall > 0) return;
int d = Link->Dir;
if(d==3) d=0; else if(d==0) d=3;
BallCounter = d*90;
BallRadius = 0;
StoreInputs();
UseBall++;
}
}

Setting up the code
Firstly, you'll need to combine the two global scripts with any you already have. (http://www.purezc.com/forums/index.php?showtopic=38773)
Find the sound effect you want to use for when the ball hits things and write down its ID number.
Make a weapon sprite for your ball head in the weapons/misc sprites section, and make a note of its ID.
Find a tile for your chain to use, and write down the tile number for that from your tilesheet.
Decide which flag you want to use for Ball->Next combotypes.
Go to the top of your script file, and set the 4 constants to be the numbers you just gathered. (// is a noted line)
Set the other values at the top of the script file to what you want them to be. They should be pretty self explanitory (the last one is either 'true' or 'false').
Setting up the item
Assign the global script to its respective slot, and the item script to a slot. Write down which slot it is.
Make a new custom item with a custom itemclass.
Set its action script to the number you just wrote down for the item script slot.
Make the custom itemclass a space in the susbcreen.

And Hey Presto!
We now have a fully-functional Ball and Chain item.

Miscellaneous
The flag you choose will function as a ball->next flag.
As a placed flag, the combo will change to the next combo in the list and the flag will be removed when you hit it with the ball
As an inherent flag, it functions pretty similar.
If you get hurt while you're spinning, you'll drop the ball.

And thanks to Weasels from PureZC for bothering me to write it.