Tukki
is Skeleton Pirate.
- Reaction score
- 29
Ammo System
v1.0
v1.0
A simple ammo system with the main purpose to be as easy to use as possible. Can use food, gold/lumber or other ways of ammo info.
Requirements:
- A vJass compiler (such as JNGP);
- Small knowledge of calling functions;
- PUI v5.1;
- A Reload ability;
JASS:
//===========================================================================
// Ammo System -- v1.0
//===========================================================================
//
// A simple yet useful ammo system which can use food, gold&lumber or other
// ways to display ammo and clips.
//
// Coder: Tukki
// Requirements:
// - a reload ability
// - this trigger
// - PUI by Cohadar [v5.1]
// - a vJass compiler such as JassNewGenPack 1.5b+
//
// Importing:
// -(1) Left-click on 'Ammo System', press Ctrl+C
// -(2) Open your map and open Trigger Editor, press Ctrl+V
// - Repeat the process(1 and 2) with PUI if you don't have it
// - Create or copy the 'Reload' ability found in this map
// - Change the AID_RELOAD to the rawcode of the ability
// press Ctrl+D in Object Editor to view rawcodes
//
// Functions Provided:
//
// Ammo_Add(whichUnit, amount, whichType) -> nothing
// Ammo_Get(whichUnit, whichType) -> integer (-1 if invaild)
// Ammo_Create(whichUnit, startingAmmo, startingClips, maxAmmo, maxClips)
//
// Example: call Ammo_Create(GetTriggerUnit(), 30, 5, 30, 10)
//
// will: make the unit have 5 initial clips + the one active
// restrict clip maximum to 10 and ammo maximum to 30
//
// Pros:
//
// * Supports several types of ammo/clip display
// * Easy-to-use, even for GUI:ers
// * Uses PUI for unit-struct attaching
//
// Cons:
//
// * Does not recycle/destroy structs
// * 8190 unit-limit
// * Unit-stopping is not 100% accurate, depending on the attack rate
//
//===========================================================================
library Ammo initializer init uses PUI
globals
private constant boolean USE_FOOD_ALL = true // Use the food counter to display
private constant boolean USE_GOLD_AND_LUMBER = false // current ammo/current clips or
// gold&lumber resources.
// Set both to false if you use a
// multiboard.
constant integer AMMO_TYPE_CLIP = 0 // Use this "names" as whichType in the Get&Add
constant integer AMMO_TYPE_AMMO = 1 // functions.
constant integer AMMO_TYPE_MAX_CLIP = 2
constant integer AMMO_TYPE_MAX_AMMO = 3
private constant integer AID_RELOAD = 039;A000039; // Rawcode of the Reload ability
private constant string OID_RELOAD = "absorb" // Order string of formentioned ability
private constant boolean AUTO_RELOAD = true // Auto-reload when out of ammo?
private constant string NO_AMMO = "|CFFEE0000Out of ammo!|r" // no-ammo error text
private constant string NO_CLIP = "|CFFEE0000Out of clips!|r" // no-clips error text
private constant string RELOAD = "|CFF00EE00Reloading!|r" // reloading text
private constant real REMINDER = 2.0 // how often error triggered texts may appear
private constant real TT_SIZE = 0.024 // Error text size
private constant real TT_VELOCITY = 0.02 // Error text velocity
private constant real TT_LIFETIME = 3.0 // Error text lifespan
private constant real TT_FADE = TT_LIFETIME*0.66 // Error text fadepoint
endglobals
//---------------------------------------------------------------------------
private function TextTag takes unit u, player p, string s returns nothing
local texttag t=CreateTextTag()
call SetTextTagText(t, s, TT_SIZE)
call SetTextTagPos(t, GetUnitX(u), GetUnitY(u), 0)
call SetTextTagPermanent(t, false)
call SetTextTagVisibility(t, GetLocalPlayer()==p)
call SetTextTagFadepoint(t, TT_FADE)
call SetTextTagLifespan(t, TT_LIFETIME)
call SetTextTagColor(t, 255, 255, 255, 255)
call SetTextTagVelocity(t, 0, TT_VELOCITY)
set t=null
endfunction
//---------------------------------------------------------------------------
private struct unitData
unit whichUnit
integer currentAmmo=0
integer currentClips=0
integer maxAmmo=0
integer maxClips=0
real last=0
//! runtextmacro PUI()
static group Pivot=null
static timer Timer=null
//---------------------------------------------------------------------------
static method create takes unit u, integer sa, integer sc, integer ma, integer mc returns unitData
local unitData this = unitData.allocate()
set .whichUnit=u
set .currentAmmo=sa
set .currentClips=sc
set .maxAmmo=ma
set .maxClips=mc
call .update()
call GroupAddUnit(unitData.Pivot, u)
set unitData<u>=this
return this
endmethod
//---------------------------------------------------------------------------
method update takes nothing returns nothing
if(USE_GOLD_AND_LUMBER)then
call SetPlayerState(GetOwningPlayer(.whichUnit), PLAYER_STATE_RESOURCE_GOLD, .currentAmmo)
call SetPlayerState(GetOwningPlayer(.whichUnit), PLAYER_STATE_RESOURCE_LUMBER, .currentClips)
elseif(USE_FOOD_ALL)then
call SetPlayerState(GetOwningPlayer(.whichUnit), PLAYER_STATE_RESOURCE_FOOD_USED, .currentAmmo)
call SetPlayerState(GetOwningPlayer(.whichUnit), PLAYER_STATE_RESOURCE_FOOD_CAP, .currentClips)
endif
endmethod
//---------------------------------------------------------------------------
static method onAttackEvent takes nothing returns nothing
local unit u=GetAttacker()
local unitData this=unitData<u>
if(.currentAmmo>0)then
set .currentAmmo=.currentAmmo-1
call .update()
else
call PauseUnit(u, true)
call IssueImmediateOrder(u, "stop")
call PauseUnit(u, false)
if(.currentClips>0)then
if(AUTO_RELOAD)then
call IssueImmediateOrder(u, OID_RELOAD)
call TextTag(u, GetOwningPlayer(u), RELOAD)
else
call PauseUnit(u, true)
call IssueImmediateOrder(u, "stop")
call PauseUnit(u, false)
if (TimerGetElapsed(unitData.Timer)-.last>REMINDER)then
call TextTag(u, GetOwningPlayer(u), NO_AMMO)
set .last=TimerGetElapsed(unitData.Timer)
endif
endif
endif
endif
set u=null
endmethod
//---------------------------------------------------------------------------
static method onSpellEvent takes nothing returns nothing
local unit u=GetSpellAbilityUnit()
local unitData this=unitData<u>
if(.currentClips>0)then
set .currentAmmo=.maxAmmo
set .currentClips=.currentClips-1
call .update()
else
call TextTag(u, GetOwningPlayer(u), NO_CLIP)
endif
set u=null
endmethod
//---------------------------------------------------------------------------
static method checkAttack takes nothing returns boolean
return IsUnitInGroup(GetAttacker(), unitData.Pivot)
endmethod
//---------------------------------------------------------------------------
static method checkSpell takes nothing returns boolean
return IsUnitInGroup(GetSpellAbilityUnit(), unitData.Pivot) and GetSpellAbilityId()==AID_RELOAD
endmethod
endstruct
//---------------------------------------------------------------------------
public function Add takes unit whichUnit, integer amount, integer state returns nothing
local unitData d=unitData[whichUnit]
if(d==0)then
debug call BJDebugMsg("|CFFEE0000"+SCOPE_NAME+" error: "+GetUnitName(whichUnit)+" is not indexed!|r")
return
endif
if(state==AMMO_TYPE_CLIP)then
if(d.currentClips+amount>d.maxClips)then
set d.currentClips=d.maxClips
else
set d.currentClips=d.currentClips+amount
endif
elseif(state==AMMO_TYPE_AMMO)then
if(d.currentAmmo+amount>d.maxAmmo)then
set d.currentAmmo=d.maxAmmo
else
set d.currentAmmo=d.currentAmmo+amount
endif
elseif(state==AMMO_TYPE_MAX_AMMO)then
set d.maxAmmo=amount
elseif(state==AMMO_TYPE_MAX_CLIP)then
set d.maxClips=amount
endif
call d.update()
endfunction
//---------------------------------------------------------------------------
public function Get takes unit whichUnit, integer state returns integer
local unitData d=unitData[whichUnit]
if(state==AMMO_TYPE_AMMO)then
return d.currentAmmo
elseif(state==AMMO_TYPE_CLIP)then
return d.currentClips
elseif(state==AMMO_TYPE_MAX_CLIP)then
return d.maxClips
elseif(state==AMMO_TYPE_MAX_AMMO)then
return d.maxAmmo
endif
return -1
endfunction
//---------------------------------------------------------------------------
public function Create takes unit whichUnit, integer startAmmo, integer startClips, integer maxAmmo, integer maxClips returns nothing
call unitData.create(whichUnit, startAmmo, startClips, maxAmmo, maxClips)
endfunction
//---------------------------------------------------------------------------
private function restart takes nothing returns nothing
call TimerStart(unitData.Timer, 3600, false, function restart)
endfunction
//---------------------------------------------------------------------------
private function init takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED)
call TriggerAddCondition(t, Condition(function unitData.checkAttack))
call TriggerAddAction(t, function unitData.onAttackEvent)
set t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function unitData.checkSpell))
call TriggerAddAction(t, function unitData.onSpellEvent)
set unitData.Pivot=CreateGroup()
set unitData.Timer=CreateTimer() // I hope this doesn't kill the world..
call TimerStart(unitData.Timer, 3600, false, function restart)
endfunction
endlibrary</u></u></u>
How to use:
JASS:
call Ammo_Create(<someUnit>, <startAmmo>, <startClips>, <maxAmmo>, <maxClips>)
Screenshots: I like systems that doesn't benefit from these things
Change log:
- 30.01.2009 - v1.0 released
Upcoming Features:
- Directly using Gold/Lumber/Food for ammo usage (currently it's only changing them)