Copy to Clipboard Test

Automated Weapon or Item (Auto-Fire) Code

import "std.zh"

import "ItemHandling.zh" //Requires v6.7 or higher.
import "Timers.zh" //Requires v1.0 or higher.


//////////////////////////////
/// Automatic Item ///////////
/// v2.1 6th May, 2017     ///
/// Creator: ZoriaRPG      ///
//////////////////////////////

///Variables, Arrays, and Constants

const int I_REPEAT = 14; //Default repeating item.

//Timers.zh array, timer ID. 
const int TI_REPEAT = 0;

//int AutoFireStoredItem; //Holds the value of the B-Slot item, between automatic activations.

//An array for the repeating item. 
int AutoFire[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 100, 1 }; 

//AutoFire Indices:
const int AUTOFIRE_REPEAT_TIME = 8;
const int AUTOFIRE_SPEED = 9; //Index for array. 
const int AUTOFIRE_ENABLED = 7; 
const int AUTOFIRE_STOREDITEM = 6; 
const int AUTOFIRE_ITEM = 5; 

const int AUTOFIRE_R_DISABLES = 1; //If set to '1', and autofiring, the player may press R to turn off autofire. 

//! Accessors

//Set or get the item to autofire. 
void SetRepeatingItem(int itm) { AutoFire[AUTOFIRE_ITEM] = itm; }
int GetRepeatingItem() { return AutoFire[AUTOFIRE_ITEM]; }

//Set or get a custom rate of timer decrement. Default is 1. 
void SetAutoFireDecrementRate(int v) { AutoFire[AUTOFIRE_SPEED] = v; }
int GetAutoFireDecrementRate() { return AutoFire[AUTOFIRE_SPEED]; }

//Sets or get a custom delay. Default is 100. 
void SetAutoFireDelay(int v) { AutoFire[AUTOFIRE_REPEAT_TIME] = v; }
int GetAutoFireDelay() { return AutoFire[AUTOFIRE_REPEAT_TIME]; }

//Set or get autofire status. 
bool isAutoFire(){  return ( AutoFire[AUTOFIRE_ENABLED] != 0 ); }
void isAutoFire(bool a){
	if ( a ) AutoFire[AUTOFIRE_ENABLED] = 1;
	else AutoFire[AUTOFIRE_ENABLED] = 0;
}

//Set or get the stored equipment item. 
int AutoFireStoredItem() { return AutoFire[AUTOFIRE_STOREDITEM]; }
void AutoFireStoredItem(int a){ AutoFire[AUTOFIRE_STOREDITEM] = a; }

///Global Scripts

global script Init{
    void run(){
        setTimer(TI_REPEAT, 0);
    }
}
    
global script onExit{
	void run(){
		setTimer(TI_REPEAT, 0);
	}
}

global script activeRepeatingItem{
	void run(){
		while(true){
			setTimer(TI_REPEAT,GetAutoFireDelay());
			startTimer(TI_REPEAT);
			setRepeatOff();
			reduceTimer(TI_REPEAT,GetAutoFireDecrementRate());
			AutofireInitiate(LW_ARROW);

			Waitdraw();
			RevertItemAfterFiring();
			//Trace(returnTimer(TI_REPEAT)); //Print value to allegro.log.
			//AutofireUpdate(); //Disabled, not needed for this version.
		    
			Waitframe();
			}
		}
}

//Item Scripts

//This item simply triggers the boolean isAutoFire to true, or false. You can expand on this by using a boolean array.

//D0 is the item to autofire.
//D1 is the delay in frames before firing. 
//D2 is the timer decrement value (as an optional override to the default of '1')
item script repeatingWeapon{
	void run(int repeat, int timer, int decrement){
		//Sanity check for the item. 
		if ( repeat > 0 && repeat < 256 ) SetRepeatingItem(repeat); 
		//Default
		else SetRepeatingItem(I_REPEAT); 
		if ( timer > 0 ) { 
			timer = timer << 0; //Truncate
			SetAutoFireDelay(timer);
		}
		if ( decrement > 0 && decrement < timer ) {
			decrement = decrement << 0; 
			SetAutoFireDecrementRate(decrement);
		}

		isAutoFire(!isAutoFire()); //Flip the state.  
		//int ss[]="Tracing isAutoFire(): ";
		//TraceS(ss); TraceB(isAutoFire());
	}
}

//Functions

//Initiates autofiring mode. 
void AutofireInitiate(int lType){
	if ( isAutoFire() && !lWeaponExists(lType) && checkTimer(TI_REPEAT) ){
		AutoFireStoredItem(GetEquipmentB());
		SetItemB(GetRepeatingItem());
		Link->InputB = true;
		Waitframe();
		if ( GetEquipmentB() == GetRepeatingItem() ) {
		    SetItemB(AutoFireStoredItem());
		}
	}
        else { 
		AutoFireStoredItem(GetEquipmentB());
		if ( GetEquipmentB() != AutoFireStoredItem() ) {
			SetItemB(AutoFireStoredItem());
		}
        }
}

//Called after firing, to restore the item in slot B. 
void RevertItemAfterFiring(){
	if ( GetEquipmentB() == GetRepeatingItem() ) {
		SetItemB(AutoFireStoredItem());
        }
        else { 
		AutoFireStoredItem(GetEquipmentB());
		if ( GetEquipmentB() != AutoFireStoredItem() ) {
			SetItemB(AutoFireStoredItem());
		}
        }
}

//Initialises automatic firing of a weapon, or automatic use of an item that is not an lweapon. 
void AutofireInitiate(int repeatingItem, bool notLType){
	if ( isAutoFire() && checkTimer(TI_REPEAT) ){
		AutoFireStoredItem(GetEquipmentB());
		SetItemB(repeatingItem);
		Link->InputB = true;
		Waitframe();
		if ( GetEquipmentB() == repeatingItem ) {
			SetItemB(AutoFireStoredItem());
		}
	}
        else { 
		AutoFireStoredItem(GetEquipmentB());
		if ( GetEquipmentB() != AutoFireStoredItem() ) {
			SetItemB(AutoFireStoredItem());
		}
        }
}

//Emergency function to turn boolean off by pressing R.
void setRepeatOff(){
	if ( AUTOFIRE_R_DISABLES && Link->PressR && isAutoFire() ){
		isAutoFire(false);
	}
}