System Ammo System

Tukki

is Skeleton Pirate.
Reaction score
29
Ammo System
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  = 'A000'   // 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&gt;0)then
                    set .currentAmmo=.currentAmmo-1
                    call .update()
                else
                    call PauseUnit(u, true)
                    call IssueImmediateOrder(u, &quot;stop&quot;)
                    call PauseUnit(u, false)
                    if(.currentClips&gt;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, &quot;stop&quot;)
                            call PauseUnit(u, false)
                            if (TimerGetElapsed(unitData.Timer)-.last&gt;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&gt;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(&quot;|CFFEE0000&quot;+SCOPE_NAME+&quot; error: &quot;+GetUnitName(whichUnit)+&quot; is not indexed!|r&quot;)
                return
            endif
            if(state==AMMO_TYPE_CLIP)then
                if(d.currentClips+amount&gt;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&gt;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&#039;t kill the world..
        
        call TimerStart(unitData.Timer, 3600, false, function restart)
    endfunction
endlibrary</u></u></u>


How to use:
JASS:
call Ammo_Create(&lt;someUnit&gt;, &lt;startAmmo&gt;, &lt;startClips&gt;, &lt;maxAmmo&gt;, &lt;maxClips&gt;)


Screenshots: I like systems that doesn't benefit from these things :D

Change log:
  • 30.01.2009 - v1.0 released

Upcoming Features:
  • Directly using Gold/Lumber/Food for ammo usage (currently it's only changing them)
 

Attachments

  • AmmoSystem.w3x
    54.9 KB · Views: 280

duderock101

Check out my 2 Player Co-op RPG!
Reaction score
71
hmm, a jass version of ammo system, looks good ( i dunno anything bout jass hehhe), if you don't know jass use my system (its simpler and in GUI) hehe well +rep for you
 

Tukki

is Skeleton Pirate.
Reaction score
29
hmm, a jass version of ammo system, looks good ( i dunno anything bout jass hehhe), if you don't know jass use my system (its simpler and in GUI) hehe well
Maybe you should learn vJass/JASS :) I'll check your system out.
 

psychophat

New Member
Reaction score
0
Nice, could you add an update that it cannot shoot anything else if there is no ammo.

Clip still shootable.
 

Tukki

is Skeleton Pirate.
Reaction score
29
I'm not 100% sure of what you mean with "clip still shootable", are you saying that:

a - the system malfunction and the user may attack, discardig how many bullets he got?
b - that you shouldn't be able to target some things when out of ammo?
c - that it malfunctions and doesn't reduce the number of clips, a.k.a you have unlimited clips

Glad you liked it, though :)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top