找回密码
 点一下
查看: 4105|回复: 13

xe系统的几个例子供大家研究

[复制链接]
发表于 2009-1-29 11:02:15 | 显示全部楼层 |阅读模式
[jass]
//**********************************************
//* Rune of Illusions
//*
//* A quick sample for xecast
//*
//*
//I003 : rune of illusion
//A009 : Illusions (dummy)
//----------------------------------------------
scope IllusionRune initializer init

    private function itemIdMatch takes nothing returns boolean  //If the id of the pickup item
      return (  GetItemTypeId(GetManipulatedItem()) == 'I003' ) //matches I003 ...
    endfunction                                                 //

    //====================================================
    //: This time we'll use a single xecast instance for
    //: all the cases the rune is used. It is recommended
    //: to do this since it is more efficient.
    //
    globals                 // :We begin by actually declaring our cast global
        private xecast cast // variable
    endglobals              //
    private function setItUp takes nothing returns nothing //: In this function,
        set cast = xecast.create()                         //  we do some basic setup
        set cast.abilityid = 'A009'  //The ability Id for our dummy illusions ability
        set cast.orderid   = 852274  //The order id.
        //: The illusions ability is a special case since it does not have an orderstring
        //  so we are just going to use its order id, every active ability has one,
        // I got the id using a detector trigger, but most people would prefer to use
        // the order id guide: http://www.wc3campaigns.net/tools/weu/ORDERIDS.xls
        //
        //
        //
    endfunction

    private function onItemPick takes nothing returns nothing
     local xecast   xc  = xecast.createA() //CreateA so we don't have to destroy the object after the cast.
     local unit     u   = GetTriggerUnit()

        set cast.owningplayer = GetOwningPlayer(u) //* The owning player, determines who will own the illusion.
        call cast.castOnTarget( u )  //Let's call the castOnTarget method on the Triggering unit.

     set u=null
    endfunction


    private function init takes nothing returns nothing
     local trigger t=CreateTrigger() //The usual Trigger registering
       call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_PICKUP_ITEM) //: Unit pickups item
       call TriggerAddCondition(t, Condition(function itemIdMatch))         //:
       call TriggerAddAction(t, function onItemPick)

       call setItUp() //call our xecast setup function...
    endfunction

endscope






[/jass]
 楼主| 发表于 2009-1-29 11:03:00 | 显示全部楼层
Sheep staff
[jass]
//**********************************************
//* Sheep staff.
//*
//* A quick sample for xecast.AOEloc
//*
//*

//----------------------------------------------
scope SheepStaff initializer init

    private function spellIdMatch takes nothing returns boolean
      return (GetSpellAbilityId()=='A006')
    endfunction

    private function onSpellCast takes nothing returns nothing
     local xecast   xc  = xecast.createA() //CreateA so we don't have to destroy the object after the cast.
     local unit     u   = GetTriggerUnit()
     local location loc = GetSpellTargetLoc() //The target point

        call SetUnitAnimation(u, "attack") // Let's focus on the look of the item cast for a second...


        //==============================================
        // Here, we do assignments:
        //
        set xc.abilityid    = 'A005'                          //* Cast ability A005
        set xc.level        = GetUnitAbilityLevel(u, 'A006' ) //* Same level as trigger ability
        set xc.orderstring  = "polymorph"                     //* The order is polymorph
        set xc.owningplayer = GetOwningPlayer(u)              //* The owning player, determines targets and bounty credits
      
        call xc.castOnAOELoc( loc, 200.0 )                    //* Our castOnAOE call, using the location version
                                                              //* A radius of 200.0
                                                              // Since createA was used, no need to destroy the xecast object

        call RemoveLocation(loc) //We need to clean the point.

     set u=null
    endfunction


    private function init takes nothing returns nothing
     local trigger t=CreateTrigger()
        call TriggerAddCondition(t, Condition( function spellIdMatch) )
        call TriggerAddAction(t,    function onSpellCast)
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )

     set t=null
    endfunction

endscope





[/jass]
回复

使用道具 举报

 楼主| 发表于 2009-1-29 11:03:35 | 显示全部楼层
Double gem of green fire!

[jass]
//**********************************************
//* Double gem of green fire!
//* --------------------------
//* A quick sample for xecollider
//*
//*

//----------------------------------------------
scope BiGreenFire initializer init

    //
    //   Yes, usually you'll need to make a struct to use xecollider.
    // basically, xecolliders need to know what to do when they hit
    // something, when you make your own struct that extends xecollider
    // you can declare your own onUnitHit method that will be executed
    // everytime the collider hits a unit.
    //
    //   The good thing is that you can use this struct to store
    // the missile's information as well.
    //
    private struct greenMissile extends xecollider
        //
        // For example, I am storing the owner of the green missile here.
        // owner would be the hero that used the item.
        //
        unit owner

        //
        // So, the onUnitHit will fire whenever there is a collision
        // between the collider and some unit, notice you can use the
        // struct's members in this method, this is actualyl a xecollider
        // as well, so you can use all xecollider's members and methods in it.
        //
        method onUnitHit takes unit target returns nothing

            // Don't explode if the owner is "hit", often when creating the missile
            // it would think it hit the unit that created it...
            if (this.owner != target) then

                // perform the damage stuff, credit the owner.
                call UnitDamageTarget( this.owner, target, 100.0 , true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE , WEAPON_TYPE_WHOKNOWS)

                // No, do not call .destroy(), terminate is better
                call this.terminate()
            endif
        endmethod
    endstruct

    //
    // This is the function we set to run whenever the triggerer ability is
    // casted.
    //
    private function onSpellCast takes nothing returns nothing
     local unit     u   = GetTriggerUnit()    //The hero casting the spell
     local location loc = GetSpellTargetLoc() //The target point

     local real     x   = GetUnitX(u) // The position of the hero
     local real     y   = GetUnitY(u) //

     local real     ang = Atan2( GetLocationY(loc) - y, GetLocationX(loc) - x) //the angle between the target and the unit

     local real     ang2
     local integer  i

     local real     mx
     local real     my

     local greenMissile xc //notice our variable uses the greenMissile type

        call SetUnitAnimation(u, "attack") // Let's focus on the look of the item cast for a second...
        call TriggerSleepAction(0.0)

        // ang2 would be perpendicular to the other angle, we are using radians so to get
        // ang2 we add PI/2 which is equivalent to 90 degrees.
        set ang2 = ang + bj_PI/2
        set i=0             //
        loop                // we are creating two missiles but that's too much hassle and repetitive
            exitwhen (i==2) // code, just use a loop and one trick for the angle you shall see bellow
            
            set mx = x + 75*Cos(ang2) //Getting the position for the missile using a polar
            set my = y + 75*Sin(ang2) //projections.


            set xc = greenMissile.create(mx, my , ang) //create the missile, notice we are using greenMissile for create as well.
            
            // set the model path:
            set xc.fxpath = "Abilities\\\\Weapons\\\\GreenDragonMissile\\\\GreenDragonMissile.mdl"

            // a flash, see xefx's readme, it just plays a dead animation.
            call xc.flash( "Abilities\\\\Weapons\\\\GreenDragonMissile\\\\GreenDragonMissile.mdl" )

            set xc.acceleration   = 1000.0 // The missile starts with a speed of 0, acceleration of 1000
            set xc.maxSpeed       =  500.0 // and a speed cap of 500.0,
            set xc.expirationTime =    2.0 // it expires after 2 seconds.
                                           // So, try visualizing those things

            set xc.z              =   50.0 // some height, since missiles often fly...

            set xc.owner = u // important stuff, see how our collider is using the greenMissile struct
                             // so we can assign the owner, as you saw above the owner determines
                             // what can hit the missile and who to credit the damage for.


            set ang2= bj_PI + ang2 //this is the trick, the second angle will be the opposite to the
                                   // current one.
            set i=i+1
        endloop

        call RemoveLocation(loc) //We need to clean the point.

     set u=null
     set loc=null // good idea to null handle local variables.
    endfunction

    //:
    //:  Now some usual stuff, conditions, events... This is normal Jass, nothing to do with xecollider.
    //: So I think I can get away without commenting it...
    //:
    private function spellIdMatch takes nothing returns boolean
      return (GetSpellAbilityId()=='A00A')
    endfunction


    private function init takes nothing returns nothing
     local trigger t=CreateTrigger()
        call TriggerAddCondition(t, Condition( function spellIdMatch) )
        call TriggerAddAction(t,    function onSpellCast)
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )

     set t=null
    endfunction

endscope





[/jass]
回复

使用道具 举报

 楼主| 发表于 2009-1-29 11:04:02 | 显示全部楼层
FireNovaStrike
[jass]
library FireNovaStrike initializer init requires xecollider, xedamage
//**************************************************************************************
//* FireNovaStrike
//* ---------------
//*  A simple xedamage + xecollider demo.
//*  Requirements:
//*      - xecollider, xedamage
//*      - A triggerer ability, with a unit target. An example would be
//*        the FireNovaStrike ability you can find in this map's object editor.
//*      
//*************************************************************************************

   //==================================================================================
   // Config:
   //
   //
   globals
       private constant integer SPELL_ID        ='A007' //The triggerer spell id.
   endglobals

   //==================================================================================
   // Let's set the damage options up, this function takes a xedamage object d
   // which something else probably instantiated and we would like to configure.
   //
   private function setupDamageOptions takes xedamage d returns nothing
       set d.dtype = DAMAGE_TYPE_FIRE   // Do spell, fire (magic) damage
       set d.atype = ATTACK_TYPE_NORMAL //

       call d.factor( UNIT_TYPE_STRUCTURE , 0.5) //half damage to buildings.

       set d.damageEnemies = true  // This evil spell pretty much hits
       set d.damageAllies  = true  // anything that is not invulnerable or
       set d.damageNeutral = true  // the casting hero himSelf... it would
       set d.damageSelf    = false // be quite dumb if it was able to hit the hero...

   endfunction

   //**********************************************************************************
   globals
       private xedamage damageOptions
   endglobals


   //==================================================================================
   //  FireBolt struct: to make your xecolliders (in case you wish to detect events...
   // you need to extend your own struct, see it as a convenience cause it also saves
   // you the problem of attaching stuff (see how I am saving the casting unit in
   // the missile's struct so I can do damage correctly)
   //
   //
   private struct FireBolt extends xecollider //* the "extends xecollider" basically means
                                              //* your FireBolt struct represents a xecollider as well

       unit    castingHero // Accept it, you most likely had to use a struct anyway,
       integer level       // to at least attach things like these. the extends approach
                           // helps us adding fields to the missile like this

       //==============================================================================
       // The missile's onUnitHit method is called everytime it hits a unit.
       // So this method is handling the unitHit event, nice?
       //
       method onUnitHit takes unit hitunit returns nothing

           // We want the missile to 'die' automatically on impact, but we don't
           // want it to die on any impact, for example, when the missile is created
           // it will count as an impact with the casting hero... We are using xedamage's
           // damageSelf option to prevent the hero from being targeteable...

           // xedamage.allowedTarget returns true if under those options a unit would
           // be a valid target for the source, in this case, the source is the casting
           // hero (which we are retrieving from the struct's members)  while the target
           // is the unit that was just hit (which we are retrieving from the method's
           // argument)
           //
           if (damageOptions.allowedTarget( this.castingHero  , hitunit ) ) then

               //Let's make the unit look as if it is taking fire, how? Let's make a fireball effect explode on them:
               call DestroyEffect( AddSpecialEffectTarget("Abilities\\\\Weapons\\\\RedDragonBreath\\\\RedDragonMissile.mdl",hitunit, "origin") )

               // We know it is a valid target, let's damage it?
               // we are retrieving the level from the struct's members, and it is used in
               // a simple damage formula, for every level the damage increases by 25.
               call damageOptions.damageTarget(this.castingHero  , hitunit, this.level * 25.0 )

               // We wish the missile to explode
               call this.terminate()
           endif


       endmethod

       method onDestroy takes nothing returns nothing
           set this.castingHero = null //perhaps it is a good idea to null it,
                                       //well, it isn't, but I am making a sample
                                       //of how to use onDestroy here!


           // call DestroyEffect( GetAbilityEffectById('AOcl',EFFECT_TYPE_TARGET,0) , this.x , this.y )
           // uncomment this and pretty lightning effects will appear whenever one of our fire bolts
           // dies, just so you notice how onDestroy is called both after someone calls terminate()
           // and after the expiration time ends...
       endmethod

       //===============================================================================
       // just for a sample will use the loopControl event, all right, will make the
       // missile 'flash' randomly.
       //
       method loopControl takes nothing returns nothing

           if(GetRandomReal(0,1)<0.02) then //a random condition, 2% chance to flash
               
               //Please notice, a xecollider object also counts as a xefx, so all xefx's
               //methods and attributes count, in this case we are calling flash
               //
               //It makes a special effect's death animation appear on the missile.
               //
               call this.flash("Abilities\\\\Weapons\\\\RedDragonBreath\\\\RedDragonMissile.mdl")
           endif

           //Notice loopControl gets called for the missile every XE_ANIMATION_PERIOD seconds
       endmethod

   endstruct

   private function spellIdMatch takes nothing returns boolean
       return (GetSpellAbilityId()==SPELL_ID)
   endfunction

   private function onSpellEffect takes nothing returns nothing
    local integer  i=0
    local unit     tar  = GetSpellTargetUnit() //The spell's target
    local unit     hero = GetTriggerUnit()     //The spell's caster

    local real x
    local real y

    local FireBolt fb

    local effect   fx  =  AddSpecialEffectTarget("Abilities\\\\Spells\\\\Human\\\\FlameStrike\\\\FlameStrikeTarget.mdl", tar, "origin")
                          // A warning effect, will destroy this later.




       loop
           exitwhen i==20

           set x=GetUnitX(hero)
           set y=GetUnitY(hero)

           // We have pretty much most of the work up there with the fire bolt struct
           // and its fields and event handler methods.
           //
           // Let's finally capitalize that:
           //

           // The creation method for a xecollider object is (x,y, facing)
           // in this case, we wish to create the fire bolt at the hero's position
           // facing? Since there are 20 missiles, we want to devide all those 2PI
           // radians in 20 equal parts...
           //
           set fb = FireBolt.create( x, y, i*(2*bj_PI)/ 20 )

           set fb.fxpath     = "Abilities\\\\Weapons\\\\RedDragonBreath\\\\RedDragonMissile.mdl"
           // It is often a good idea to give them missiles a model... Let's use the
           // red dragon's missile model.

           set fb.speed        = 100.0  // We'll use acceleration for these bolts
           set fb.acceleration = 250.0  // let them begin with a 100.0  speed, accelerate
           set fb.maxSpeed     = 1000.0 // them at a ratio of 250 per second, and cap the
                                        // speed at 1000.0



           set fb.z = 20.0

           set fb.angleSpeed = 1.5 // We'll like the firebolts to home to the spell's target
                                   // we'll first need to give it an angleSpeed, a value of
                                   // 1.5 puts it close to 85 degrees per second (remember
                                   // everything is in radians)
                                   // The angle speed is just how much can the direction
                                   // vary in a second, it determines the homing's accuracy.
                                   //
                                   // Notice how large values here turn the spell into some sort
                                   // of giant homing fire ball, while low values make it
                                   // much closer to a traditional nova.

           set fb.targetUnit = tar // As I said, we want the firebolts to home towards
                                   // so, we use the targetUnit field for that.
                                   //
                                   // Try commenting that line out.

           set fb.expirationTime = GetRandomReal(2.0,3.0)
           // expirationTime determines the duration of the missile, I made things interesting
           // by adding a call to random, so not all the fire missiles will end at the same time
           // looks less fabricated this way.

           // Now, this is good stuff, remember the FireBolt struct is not just a xecollider
           // it is also a custom struct we just declared, we added these fields since they
           // are useful for the missile's damage:
           //
           set fb.castingHero = hero
           set fb.level       = GetUnitAbilityLevel( hero, SPELL_ID)

           set i=i+1
       endloop
       call TriggerSleepAction(0.0)
       call SetUnitAnimation( hero, "attack" )
       call DestroyEffect(fx)

    set fx=null
    set tar=null // it is good to null handle variables at the end of a function...
    set hero=null
   endfunction

   //=====================================================================================================
   // Init stuff:
   //
   private function init takes nothing returns nothing
    local trigger t=CreateTrigger()

       // Initializing the damage options:
       set damageOptions=xedamage.create()    // first instanciate a xeobject.
       call setupDamageOptions(damageOptions) // now call the function we saw before.

       //Setting up the spell's trigger:
       call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
       call TriggerAddCondition(t, Condition(function spellIdMatch))
       call TriggerAddAction(t, function onSpellEffect)
    set t=null
   endfunction
endlibrary




[/jass]
回复

使用道具 举报

 楼主| 发表于 2009-1-29 11:04:37 | 显示全部楼层
StormyDreams
[jass]
library StormyDreams initializer init requires xebasic, xepreload, xefx, xecast, xedamage, Table
//**************************************************************************************
//* StormyDreams
//* ------------
//*  Author: Vexorian.
//*  Requirements:
//*      - xecast, xefx, xepreload
//*      - The Table library
//*      - A triggerer ability, with a point target. An example would be
//*        the StormyDreams ability you can find in this map's object editor.
//*      * If you want the synergy/enable bonus casting you need:
//*           - An ability to cast, for example the default is a parasite based
//*             ability called
//*      * Synergy is based on the level of an ability specified by BONUS_SPELL_ID
//*        it could then be a passive/active ability, or a buff.
//*      
//*************************************************************************************


   //==================================================================================
   // Config:
   //
   //
   globals
       private constant integer SPELL_ID        ='A00B' //The triggerer spell id.
       private constant integer BONUS_SPELL_ID  ='AIt6' //An ability for synergy, the level of this ability affects the bonuslevel argument.
                                                        //Right now it is item damage bonus +6 , you can use any ability you want here.
                                                        //You may also leave a 0 to disable the synergy
                                                        //Having BONUS_SPELL_ID also alters the eye candy (see bellow)

       private constant integer CAST_ABILITY_ID          ='A00D' //An ability to cast on valid targets when the next conditions are met:

       private constant integer CAST_REQUIRED_LEVEL      = 0 //Minimum ability level before using the cast ability
       private constant integer CAST_REQUIRED_BONUSLEVEL = 1 //Minimum bonus ability level before using the cast ability

       //
       // MODEL_PATH_(BONUS_)_MISSILE: The missile's model path
       // MODEL_PATH_(BONUS_)_FLASH  : The flash effect, it gets played constantly on the missile.
       //
       private constant string  MODEL_PATH_MISSILE       = "Abilities\\\\Spells\\\\Other\\\\Incinerate\\\\IncinerateBuff.mdl"
       private constant string  MODEL_PATH_BONUS_MISSILE = "Abilities\\\\Weapons\\\\IllidanMissile\\\\IllidanMissile.mdl"

       private constant string  MODEL_PATH_BONUS_FLASH   = "Abilities\\\\Weapons\\\\VengeanceMissile\\\\VengeanceMissile.mdx"
       private constant string  MODEL_PATH_FLASH         = "Abilities\\\\Weapons\\\\FarseerMissile\\\\FarseerMissile.mdx"

   endglobals

   private function castOrderId takes nothing returns integer
       return OrderId("parasite")    //sorry, but it turns out these things can't be declared on global init
   endfunction

   ////
   // Some config functions:
   // -
   // radius:            "Radius", somehow determines the curve
   // speed :            Missile speed
   // maxBolts:          Max number of missiles.
   // missileCollision:  Collision size of the missile
   // damage:            Damage done by the missile during contact.
   // missileDistance:   Initial target distance (for the first missile)
   // distanceIncrement: How much the distance is incremented per missile.  
   // castRecycleDelay:  How much to wait before recycling the caster.

   private function radius takes real level returns real
       return level*0.0 + 200.0
   endfunction

   private function speed takes integer level returns integer
       return level*0+500
   endfunction

   private function maxBolts takes integer level returns integer
       return 6+level*0
   endfunction

   private function missileCollision takes real level, real bonuslevel returns real
       return 0.0*level+0.0*bonuslevel + 100.0 //65.0
   endfunction

   private function damage takes real level, real bonuslevel returns real
       return 11*level+5*bonuslevel+4.0
   endfunction

   private function missileScale takes real level, real bonuslevel returns real
       return 1.0+level*0.0  + bonuslevel*1.1
   endfunction

   private function initialDistance takes real level, real bonuslevel returns real
       return 500.0 + 0*level+0*bonuslevel
   endfunction

   private function distanceIncrement takes real level, real bonuslevel returns real
       return 100.0 + 0*level+0*bonuslevel
   endfunction

   private function castRecycleDelay takes real level, real bonuslevel returns real
       return 5.0 * level + 0.0*bonuslevel + 0.0
   endfunction

   globals
       private constant integer ALPHA_STARTING_VALUE       = 0//255
       private constant real    ALPHA_INCREMENT_PER_SECOND = 150.0
       private constant real FLASH_FX_PERIOD = 0.25 // better as a multiple of CLOCK_TICK

       private constant real INITIAL_THROW   = 0.05 // Time to wait before beginning to throw missiles
       private constant real THROW_PERIOD    = 0.35 // Period of time between every consecutive throw.

       private constant real THROW_ANIMATION_SPEED   = 4.00 //Speed factor during throw animation
       private constant real RESTORE_ANIMATION_SPEED = 1.00 //'normal' animation speed

       private constant real INITIAL_OFFSET = 60.0

       private constant real BEZIER_Z1 = 60.0  //This is equivalent to the throw height
       private constant real BEZIER_Z2 = 30.0
       private constant real BEZIER_Z3 = 180.0
       private constant real BEZIER_Z4 = 0.0   //This is equivalent to the final height


       private constant real CLOCK_TICK = XE_ANIMATION_PERIOD //animation timer delay

       // Change if necessary:
       private constant integer MAX_SPELL_LEVELS = 3
       private constant integer MAX_BONUS_LEVELS = 3
   endglobals

   private function configDamage takes integer level, integer bonuslevel, xedamage d returns nothing
   //Read xedamage's documentation to know how to configure this.
   //does not support damagetrees

           set d.tag=666

           set  d.damageAllies = true                      //True if you want it to hurt allies.
           set  d.atype = ATTACK_TYPE_NORMAL               // NORMAL (spell) attacktype
           set  d.exception = UNIT_TYPE_FLYING             // Don't hit fliers

       if(bonuslevel>0) then                           //* The bonus version:
           set  d.dtype        = DAMAGE_TYPE_UNIVERSAL     // UNIVERSAL damage, no building damage reduction

       else                                            //* The normal version:
           set  d.dtype        = DAMAGE_TYPE_LIGHTNING     // LIGHTNING (magical) damage,
           call d.factor(UNIT_TYPE_STRUCTURE, 0.33)        // does 1/3 damage to buildings.
       endif


   endfunction

//===============================================================================
// The code. Sample begins
//
   private function H2I takes handle h returns integer
       return h
       return 0
   endfunction
   private struct missile
       group   targetlog
       integer level
       integer bonuslevel
       unit    u
       real x1
       real x2
       real x3
       real x4
       real y1
       real y2
       real y3
       real y4
       real s=0
       real inc=0.01
       xefx fx
       real flashtime=0
       static integer lastid=0
   endstruct
   private struct throw
       integer level
       integer bonuslevel
       integer donetimes=0
       real    remaining=0
       integer tog=0
       boolean stop=false
       real    tx
       real    ty
       unit    u
   endstruct

   globals
       private missile array V
       private throw   array VT
       private integer N=0
       private integer NT=0
       private timer T
       private Table Tab
       private group enumgroup
       private boolexpr fetchunits
       private unit    array U
       private integer       Un
       private xecast  Cast
       private xedamage array damageconf
   endglobals

   private function fetchFilterUnit takes nothing returns boolean
       set U[Un]=GetFilterUnit()
       set Un=Un+1
       return false
   endfunction

   private function processThrow takes throw th returns boolean
    local missile m=missile.create()
    local integer l=th.level
    local real xk
    local real yk
    local real ang
    local real ang2
    local real dist
    local real ca
    local real sa


       if(integer(m)>missile.lastid) then
           set missile.lastid=integer(m)
           set m.targetlog=CreateGroup()
       else
           call GroupClear(m.targetlog)
       endif
       call SetUnitTimeScale(th.u,THROW_ANIMATION_SPEED)
       set m.x1=GetUnitX(th.u)
       set m.y1=GetUnitY(th.u)
       set ang=Atan2(th.ty-m.y1,th.tx-m.x1)

       set m.x1=m.x1+INITIAL_OFFSET*Cos(ang)
       set m.y1=m.y1+INITIAL_OFFSET*Sin(ang)

      
       if(th.tog==0) then
           set th.tog=1
           set ang2=ang+bj_PI/2
       else
           set th.tog=0
           set ang2=ang-bj_PI/2
       endif
       set m.fx=xefx.create(m.x1,m.y1,ang2)
       set m.fx.x=m.x1
       set m.fx.y=m.y1
       set m.bonuslevel=th.bonuslevel
       set m.level=l

       if(th.bonuslevel>0) then
           set m.fx.fxpath=MODEL_PATH_MISSILE
       else
           set m.fx.fxpath=MODEL_PATH_BONUS_MISSILE
       endif
       set m.fx.scale=missileScale(l,th.bonuslevel)
       set m.fx.z=BEZIER_Z1
      
       set dist=initialDistance(l,th.bonuslevel)+th.donetimes*distanceIncrement(l,th.bonuslevel)
       set m.x4=m.x1+dist*Cos(ang)
       set m.y4=m.y1+dist*Sin(ang)
       set ca=radius(l)*Cos(ang2)
       set sa=radius(l)*Sin(ang2)
       set m.x3=m.x4-4*ca
       set m.y3=m.y4-4*sa

       set m.x2=m.x1+3*ca
       set m.y2=m.y1+3*sa

       set m.fx.alpha=ALPHA_STARTING_VALUE
       set dist=SquareRoot( (m.x4-m.x1)*(m.x4-m.x1)+(m.y4-m.y1)*(m.y4-m.y1) ) //sqrt is necessary
       set m.inc=(speed(l)/dist)*CLOCK_TICK

       set m.u=th.u
       set V[N]=m
       set N=N+1

       set th.donetimes=th.donetimes+1
       if (th.donetimes>=maxBolts(l)) then
           call SetUnitTimeScale(th.u,RESTORE_ANIMATION_SPEED)
           set Tab[H2I(th.u)]=0
           return true
       else
           set th.remaining=THROW_PERIOD
       endif
    return false
   endfunction

   private function onExpire takes nothing returns nothing
    local integer i=0
    local integer n=N
    local missile m
    local throw   th
    local real s
    local real x
    local real y
    local real z
    local boolean keep
    local integer j
    local integer ab
    local real fc
    local integer k

       //missile code
       set N=0
       loop
           exitwhen i==n
           set m=V
           set s=m.s
           set s=s+m.inc
           set keep=true
           if(s>=1.000000001) then
               set s=1
               set keep=false
           endif
           set x=s*s*s*m.x4 + 3*s*s*(1-s)*m.x3 + 3*s*(1-s)*(1-s)*m.x2+(1-s)*(1-s)*(1-s)*m.x1
           set y=s*s*s*m.y4 + 3*s*s*(1-s)*m.y3 + 3*s*(1-s)*(1-s)*m.y2+(1-s)*(1-s)*(1-s)*m.y1
           set z=s*s*s*BEZIER_Z4 + 3*s*s*(1-s)*BEZIER_Z3 + 3*s*(1-s)*(1-s)*BEZIER_Z2+(1-s)*(1-s)*(1-s)*BEZIER_Z1
           set m.fx.xyangle=Atan2(y-m.fx.y,x-m.fx.x)
           set m.flashtime=m.flashtime+CLOCK_TICK
           set m.fx.alpha=m.fx.alpha+R2I(ALPHA_INCREMENT_PER_SECOND*CLOCK_TICK+0.5)
           if (m.flashtime>=FLASH_FX_PERIOD) then
               if(m.bonuslevel>0) then
                   call m.fx.flash(MODEL_PATH_BONUS_FLASH)
               else
                   call m.fx.flash(MODEL_PATH_FLASH)
               endif
               set m.flashtime=0
           endif
           set m.fx.x=x
           set m.fx.y=y
           set Un=0
           call GroupEnumUnitsInRange(enumgroup,x,y, missileCollision(m.level,m.bonuslevel)+XE_MAX_COLLISION_SIZE, fetchunits)
           set j=0
           set k=m.level*(MAX_BONUS_LEVELS+1)+m.bonuslevel //let's save this array index for later.
           loop
               exitwhen (j==Un)
               if (U[j]!=m.u) and (IsUnitInRangeXY(U[j],x,y,missileCollision(m.level,m.bonuslevel))) and not IsUnitInGroup(U[j],m.targetlog) then
                   set fc=damageconf[k].getTargetFactor(m.u, U[j])
                   if(fc!=0.0) then
                       if(m.level>=CAST_REQUIRED_LEVEL) and (m.bonuslevel>=CAST_REQUIRED_BONUSLEVEL) then
                            set Cast.owningplayer=GetOwningPlayer(m.u)
                            set Cast.level=m.level
                            set Cast.recycledelay=castRecycleDelay(m.level,m.bonuslevel)
                           call Cast.castOnTarget(U[j])
                       endif
                       call GroupAddUnit(m.targetlog,U[j])
                       //notice we are usign forceValue, since we already know the factor, it is also possible to
                       // call damageTarget directly, but that means the system will calculate the factor twice for no reason.
                       call damageconf[k].damageTargetForceValue(m.u, U[j] ,  fc* damage(m.level,m.bonuslevel)   )
                   endif
               endif
               set j=j+1
           endloop

           if(not keep) then
               call m.fx.destroy()
               call GroupClear(m.targetlog)
               call m.destroy()
           else
               set m.s=s
               set V[N]=m
               set N=N+1
           endif
           set i=i+1
       endloop

       //now call throw code, supposedly this is not called as many times as missile code, so
       // we might as well use a function call...
       set n=NT
       set NT=0
       set i=0
       loop
           exitwhen(i==n)
           set th=VT
           set th.remaining = th.remaining - CLOCK_TICK
           if th.stop or ( (th.remaining<=-0.001) and processThrow(th) ) then
               call SetUnitTimeScale(th.u,RESTORE_ANIMATION_SPEED)
               call th.destroy()
           else
               set VT[NT]=th
               set NT=NT+1
           endif
           set i=i+1
       endloop

       if(N==0) and (NT==0) then
           call PauseTimer(T)
       endif
   endfunction

   private function onSpellEffect takes nothing returns nothing
    local location loc =GetSpellTargetLoc()
    local unit u=GetTriggerUnit()
    local throw th=throw.create()

       set Tab[H2I(u)]=integer(th)
       set VT[NT]=th
       set th.level=GetUnitAbilityLevel(u,SPELL_ID)
       set th.bonuslevel=GetUnitAbilityLevel(u,BONUS_SPELL_ID)
       set th.remaining=INITIAL_THROW
       set th.tx=GetLocationX(loc)
       set th.ty=GetLocationY(loc)
       set th.u=u
       set NT=NT+1
       if(NT==1) then
           call TimerStart(T,CLOCK_TICK,true, function onExpire)
       endif

    set loc=null
    set u=null
   endfunction

   private function onSpellEnd takes nothing returns nothing
    local integer key=H2I(GetTriggerUnit())
    local throw th=throw(Tab[key])
       if(th!=0) then
           set th.stop=true
           call Tab.flush(key)
       endif
   endfunction
   private function spellIdMatch takes nothing returns boolean
       return (SPELL_ID==GetSpellAbilityId())
   endfunction

   //=====================================================================================================
   // Init stuff:
   //
   private function init takes nothing returns nothing
    local trigger t=CreateTrigger()
    local integer i
    local integer j
       call XE_PreloadAbility(CAST_ABILITY_ID)
       set Cast=xecast.create()
       set Cast.abilityid=CAST_ABILITY_ID
       set Cast.orderid=castOrderId()
       set enumgroup=CreateGroup()
       set fetchunits=Condition(function fetchFilterUnit)
       set Tab=Table.create()
       set T=CreateTimer()
       call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
       call TriggerAddCondition(t, Condition(function spellIdMatch))
       call TriggerAddAction(t, function onSpellEffect)
       set t=CreateTrigger()
       call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_ENDCAST)
       call TriggerAddCondition(t, Condition(function spellIdMatch))
       call TriggerAddAction(t, function onSpellEnd)

       set i=1

       loop
           exitwhen (i>MAX_SPELL_LEVELS)
           set j=0
           loop
               exitwhen (j>MAX_BONUS_LEVELS)
               set damageconf[i*(MAX_BONUS_LEVELS+1) +j]=xedamage.create()
               call configDamage(i,j, damageconf[i*(MAX_BONUS_LEVELS+1)+j] )
               set j=j+1
           endloop
           set i=i+1
       endloop


    set t=null
   endfunction
endlibrary




[/jass]
回复

使用道具 举报

发表于 2009-1-29 14:01:42 | 显示全部楼层
敢来点中文么?
回复

使用道具 举报

发表于 2009-1-29 14:36:16 | 显示全部楼层
进来看看有什么xe的地方
回复

使用道具 举报

发表于 2009-1-30 19:35:14 | 显示全部楼层
给些介绍,说明啊
回复

使用道具 举报

 楼主| 发表于 2009-2-18 10:25:02 | 显示全部楼层
一个物品栏系统的个人改版
PUI版
[jass]
globals
private constant  integer Cancel_ItemID= 'I00K'
// Rawcode of the Cancel item.
private constant integer BackpackMenu_ItemID='I009'
// Rawcode of the Backpack item.
private constant integer SwitchPage_ItemID = 'I00N'
// Rawcode of the Switch Page item.
private constant integer EquipmentMenu_ItemID ='I00L'
// Rawcode of the Equipment Menu item.
private constant integer HeadFiller_ItemID='I00M'
// Rawcode of the Head item.
private constant integer ArmorFiller_ItemID='I00G'
// Rawcode of the Armor item.
private constant integer WeaponFiller_ItemID ='I00H'
// Rawcode of the Weapon item.
private constant integer ShieldFiller_ItemID='I00I'
// Rawcode of the Shield item.
private constant integer AccessoryFiller_ItemID = 'I00J'
// Rawcode of the Accessory item.
private constant integer BackpackSize=16
// The number of items that can be in a Hero's Backpack. MUST be a multiple of 4.
private constant real InventorySafeX =-2040.00
// The X coordinate of a safe place to place items, so computer units won't be able to pick the up.
private constant real InventorySafeY=2040.00
// The Y coordinate of a safe place to place items, so computer units won't be able to pick the up.


private struct ItemBonuses
integer dmg
integer arm
integer hp
integer mp
integer str
integer agi
integer int
integer abil

method SetItemBonuses takes  integer dmg, integer arm, integer hp, integer mp, integer str, integer agi, integer int, integer abi returns nothing
//! textmacro NumericalBonuses takes member
if this.$member$>0
set this.$member$=$member$
//! endtextmacro
//! runtextmacro Increase("dmg")
//! runtextmacro Increase("arm")
//! runtextmacro Increase("hp")
//! runtextmacro Increase("mp")
//! runtextmacro Increase("str")
//! runtextmacro Increase("agi")
//! runtextmacro Increase("int")
//! runtextmacro Increase("abi")

endmethod
endstruct

endglobals

private function H2I takes handle h returns integer
    return h
    return 0
endfunction

function SetUpItemBonuses takes item i,integer dmg,integer arm, integer hp, integer mp, integer str, integer agi, integer int, integer abi returns nothing
local itemid=I2S(H2I(i))
set ItemBonuses itemid=ItemBonuses.create()
call  itemid.SetItemBonuses=(dmg,arm,hp,mp,str,agi,int,abi)
endfunction

globals
private group AAAInventoryGroup
private item array BP_I1 //背包1
private item array BP_I2
private item array BP_I3
private item array BP_I4

private item array QM_I1 //快捷菜单
private item array QM_I2
private item array QM_I3
private item array QM_I4

private item array BackpackMenu
private item array EquipmentMenu
private item array Cancel
private item array SwitchPage

private item array HeadFiller
private item array HeadItem

private item array ArmorFiller
private item array ArmorItem

private item array WeaponFiller
private item array WeaponItem

private item array ShieldFiller
private item array ShieldItem

private item array AccessoryFiller
private item array AccessoryItem

private integer array CurrentMenu //当前菜单 current menu
private integer array CurrentBackpackPage //CurrentBackpackPage




//=============================================================================================new..............................
function BackpackHasEmptySlots takes unit u returns boolean
      local integer id = GetUnitIndex(u)
      return BP_I1[id]== null or BP_I2[id]==null or BP_I3[id]==null or BP_I4[id]==null
endfunction

function QuickMenuHasEmptySlots takes unit u returns boolean
      local integer id = GetPlayerId(GetOwningPlayer(u))
      return QM_I1[id]== null or QM_I2[id]==null or QM_I3[id]==null or QM_I4[id]==null
endfunction

function IsItemFiller takes item i returns boolean
      local integer id = GetItemTypeId(i)
      return id == HeadFiller_ItemID() or id == ArmorFiller_ItemID() or id == WeaponFiller_ItemID() or id == ShieldFiller_ItemID() or id == AccessoryFiller_ItemID()
endfunction
//================================================================
function BackpackContainsItem takes unit u, item i returns boolean
         local integer id = GetPlayerId(GetOwningPlayer(u))
         return BP_I1[id]== i or BP_I2[id]==i or BP_I3[id]==i or BP_I4[id]==i
endfunction

function QuickMenuContainsItem takes unit u, item i returns boolean
      local integer id = GetPlayerId(GetOwningPlayer(u))
      return QM_I1[id]== i or QM_I2[id]==i or QM_I3[id]==i or QM_I4[id]==i
endfunction      

function IsEquipmentSlotValid takes string es returns boolean
      return es == "Head" or es == "Armor" or es == "Weapon" or es == "Shield" or es == "Accessory"
endfunction

//===========================这里还有cache
function GetItemEquipmentSlot takes item i returns string
      return GetStoredString(InventoryCache(), I2S(CS_H2I(i)), "equipmentslot")
endfunction
//====================================================
function GetItemSlot takes unit u, item i returns integer
      local integer a = 0
      loop
            exitwhen a > 5
            if UnitItemInSlot(u, a) == i then
                  return a
            endif
            set a = a + 1
      endloop
      return -1
endfunction

function SlotToFillerName takes integer s returns string
      if s == 0 then
            return "Head"
      elseif s == 1 then
            return "Armor"
      elseif s == 2 then
            return "Weapon"
      elseif s == 3 then
            return "Shield"
      elseif s == 4 then
            return "Accessory"
      else
            return "Cancel"
      endif
endfunction

function FillerNameToSlot takes string es returns integer
      if es == "Head" then
            return 0
      elseif es == "Armor" then
            return 1
      elseif es == "Weapon" then
            return 2
      elseif es == "Shield" then
            return 3
      elseif es == "Accessory" then
            return 4
      endif
      return 5
endfunction

function InventoryRemoveItem takes unit u, item i returns nothing
      call SetItemUserData(i, 1)
      call UnitRemoveItem(u, i)
      call SetItemPosition(i, InventorySafeX(), InventorySafeY())
      call SetItemVisible(i, false)
endfunction

function InventoryAddItem takes unit u, item i returns nothing
      call SetItemUserData(i, 0)
      call SetItemVisible(i, true)
      call UnitAddItem(u, i)
endfunction


function CreateExtendedInventory takes unit u returns nothing
      local item i
      local integer id = GetPlayerId(GetOwningPlayer(u))

      local integer a = 0
      loop
            exitwhen a > 5
            call RemoveItem(UnitItemInSlot(u, a))
            set a = a + 1
      endloop
      call GroupAddUnit(AAAInventoryGroup, u)
      set  CurrentMenu[id]=0
      set  CurrentBackpackPage[id]=1
      call UnitAddItemToSlotById(u, EquipmentMenu_ItemID(), 4)
      set i = UnitItemInSlot(u, 4)
      set EquipmentMenu[id]=i
      call UnitAddItemToSlotById(u, BackpackMenu_ItemID(), 5)
      set i = UnitItemInSlot(u, 5)
      set BackpackMenu[id]=i

      set i = CreateItem(Cancel_ItemID(), 0, 0)
      call SetItemVisible(i, false)
      set Cancel[id]=i

      set i = CreateItem(SwitchPage_ItemID(), 0, 0)
      call SetItemVisible(i, false)
      set SwitchPage[id]=i
      call SetItemCharges(i, 1)
      
//! textmacro CreatFilerItem takes ItemFillerId, ItemFiller,EquipPosition
      set i = CreateItem(ItemFillerId(), 0, 0)
      call SetItemVisible(i, false)
      set ItemFiller[id]=i
      set EquipPosition[id]=i
//! endtextmacro
//! runtextmacro CreatFilerItem(HeadFiller_ItemID,HeadFiller,HeadItem)
//! runtextmacro CreatFilerItem(ArmorFiller_ItemID,ArmorFiller,ArmorItem)
//! runtextmacro CreatFilerItem(WeaponFiller_ItemID,WeaponFiller,WeaponItem)
//! runtextmacro CreatFilerItem(ShieldFiller_ItemID,ShieldFiller,ShieldItem)
//! runtextmacro CreatFilerItem(AccessoryFiller_ItemID,AccessoryFiller,AccessoryItem)

      set i = null
endfunction

function DestroyExtendedInventory takes unit u returns nothing

      local integer id = GetPlayerId(GetOwningPlayer(u))      
      local item i
      local item t
      local integer a = 1

      set BP_I1[id]=null
      set BP_I2[id]=null
      set BP_I3[id]=null
      set BP_I4[id]=null
      
      set QM_I1[id]=null
      set QM_I2[id]=null
      set QM_I3[id]=null
      set QM_I4[id]=null
      
      set EquipmentMenu[id]=null
      call RemoveItem(GetTableItem(s, "EquipmentMenu"))
      call RemoveItem(GetTableItem(s, "BackpackMenu"))
      call RemoveItem(GetTableItem(s, "Cancel"))
      call RemoveItem(GetTableItem(s, "SwitchPage"))
      set a = 0
      loop
            exitwhen a > 4
            set i = GetTableItem(s, SlotToFillerName(a)+"Item")
            set t = GetTableItem(s, SlotToFillerName(a)+"Filler")
            if i != t then
                  call RemoveItem(i)
            endif
            call RemoveItem(t)
            set a = a + 1
      endloop
      call DestroyTable(s)
      call GroupRemoveUnit(udg_AAAInventoryGroup, u)
      call AttachString(u, "InventoryTable", "")
      set i = null
      set t = null
endfunction

function InventoryError takes unit u, string e returns nothing
      call CS_Error(GetOwningPlayer(u), e)
      call PauseUnit(u, true)
      call IssueImmediateOrder(u, "stop")
      call PauseUnit(u, false)
endfunction
[/jass]
回复

使用道具 举报

 楼主| 发表于 2009-2-18 10:25:52 | 显示全部楼层
vjass版
[jass]
globals
private constant  integer Cancel_ItemID= 'I00K'
// Rawcode of the Cancel item.
private constant integer BackpackMenu_ItemID='I009'
// Rawcode of the Backpack item.
private constant integer SwitchPage_ItemID = 'I00N'
// Rawcode of the Switch Page item.
private constant integer EquipmentMenu_ItemID ='I00L'
// Rawcode of the Equipment Menu item.
private constant integer HeadFiller_ItemID='I00M'
// Rawcode of the Head item.
private constant integer ArmorFiller_ItemID='I00G'
// Rawcode of the Armor item.
private constant integer WeaponFiller_ItemID ='I00H'
// Rawcode of the Weapon item.
private constant integer ShieldFiller_ItemID='I00I'
// Rawcode of the Shield item.
private constant integer AccessoryFiller_ItemID = 'I00J'
// Rawcode of the Accessory item.
private constant integer BackpackSize=16
// The number of items that can be in a Hero's Backpack. MUST be a multiple of 4.
private constant real InventorySafeX =-2040.00
// The X coordinate of a safe place to place items, so computer units won't be able to pick the up.
private constant real InventorySafeY=2040.00
// The Y coordinate of a safe place to place items, so computer units won't be able to pick the up.


private struct InV
unit u

group AAAInventoryGroup

item array BackpackItem
item array QuickMenuItem

item BackpackMenu
item EquipmentMenu
item Cancel
item SwitchPage

item HeadFiller
item HeadItem

item ArmorFiller
item ArmorItem

item WeaponFiller
item WeaponItem

item ShieldFiller
item  ShieldItem

item AccessoryFiller
item AccessoryItem

integer CurrentMenu //当前菜单 current menu
integer CurrentBackpackPage //CurrentBackpackPage

static method BackpackHasEmptySlots takes unit u returns boolean
      local Inv InvData=Inv(Invtable(H2I(u)))
      local integer a = 1
      loop
            exitwhen a > BackpackSize()
            if InvData.BackpackItem[a] == null then
                  return true
            endif
            set a = a+1
      endloop
      return false


endmethod
      
endstruct
endglobals

private function H2I takes handle h returns integer
    return h
    return 0
endfunction

function QuickMenuHasEmptySlots takes string s returns boolean
      return GetTableItem(s, "QuickMenuItem1") == null or GetTableItem(s, "QuickMenuItem2") == null or GetTableItem(s, "QuickMenuItem3") == null or GetTableItem(s, "QuickMenuItem4") == null
endfunction

function Init_AAAInventory takes nothing returns nothing
      local trigger t = CreateTrigger()
      local trigger u = CreateTrigger()
      local trigger d = CreateTrigger()
      local trigger o = CreateTrigger()
      call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
      call TriggerAddCondition(t, Condition( function InventoryDragItemConditions))
      call TriggerAddAction(t, function InventoryDragItemActions)
      call TriggerRegisterAnyUnitEventBJ( u, EVENT_PLAYER_UNIT_USE_ITEM )
      call TriggerAddCondition(u, Condition(function InventoryUnitUsesItemConditions))
      call TriggerAddAction(u, function InventoryUnitUsesItemActions)
      call TriggerRegisterAnyUnitEventBJ( d, EVENT_PLAYER_UNIT_DROP_ITEM )
      call TriggerAddCondition(d, Condition(function InventoryDropItemConditions))
      call TriggerAddAction(d, function InventoryDropItemActions)
      call TriggerRegisterAnyUnitEventBJ(o, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
      call TriggerAddCondition(o, Condition(function InventoryOrderConditions))
      call TriggerAddAction(o, function InventoryOrderActions)
      set t = null
      set u = null
      set d = null
      set o = null
      
      set Invtable=Table.create()
     endfunction

//===========================================================================
function InitTrig_AAAInventory takes nothing returns nothing
      call ExecuteFunc("Init_AAAInventory")
endfunction
[/jass]
回复

使用道具 举报

 楼主| 发表于 2009-2-23 20:12:00 | 显示全部楼层
[jass]
//===========================================================================
//  vJASS version of weaaddar's GetItemCostById system
//===========================================================================
//
//  * Uses Table system
//  * Fixed an issue that could happen if item cost was zero for both gold and lumber
//  * This version is compatible with original one
//  * Added some helper functions: GetItemGoldCost, GetItemLumberCost, GetItemGoldCostById, GetItemLumberCostById
//
//===========================================================================
library GetItemCostById initializer Init uses Table

globals
    private constant player  BuyerPlayer = Player(15)
    private constant integer BuyerTypeId = 'hpal'
    private constant integer ShopTypeId = 'nshe'
    private constant integer MAX_PRICE = 50000
   
    // check Init function
    private Table GoldPrice = 0
    private Table LumberPrice = 0
    private unit Buyer = null
    private unit Shop = null
endglobals

//===========================================================================
//  whichtype == true --> gold
//  whichtype == false --> lumber
//===========================================================================
function GetItemCostById takes integer id, boolean whichtype returns integer
    local integer gold
    local integer lumber

    if GoldPrice.exists(id) then
        set gold = GoldPrice[id]
        set lumber = LumberPrice[id]
    else
        call SetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_GOLD,   MAX_PRICE)
        call SetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_LUMBER, MAX_PRICE)
        call AddItemToStock(Shop, id, 1, 1)
        call IssueNeutralImmediateOrderById(BuyerPlayer, Shop, id)
        call RemoveItem(UnitItemInSlot(Buyer, 0))
        call RemoveItemFromStock(Shop, id)
        set gold   = MAX_PRICE - GetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_GOLD)
        set lumber = MAX_PRICE - GetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_LUMBER)
        set GoldPrice[id] = gold
        set LumberPrice[id] = lumber
    endif
   
    if whichtype then
        return gold
    else
        return lumber
    endif
endfunction

//===========================================================================
function GetItemGoldCost takes item i returns integer
    return GetItemCostById(GetItemTypeId(i), true)
endfunction

//===========================================================================
function GetItemLumberCost takes item i returns integer
    return GetItemCostById(GetItemTypeId(i), false)
endfunction

//===========================================================================
function GetItemGoldCostById takes integer id returns integer
    return GetItemCostById(id, true)
endfunction

//===========================================================================
function GetItemLumberCostById takes integer id returns integer
    return GetItemCostById(id, false)
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local rect r = GetWorldBounds()
   
    set Buyer = CreateUnit(BuyerPlayer, BuyerTypeId, 0, 0, 0)
    call SetUnitX(Buyer, GetRectMaxX(r))
    call SetUnitY(Buyer, GetRectMaxY(r))
   
    set Shop = CreateUnit(BuyerPlayer, ShopTypeId, 0, 0, 0)
    call SetUnitX(Shop,GetRectMaxX(r))
    call SetUnitY(Shop,GetRectMaxY(r))
   
    call UnitAddAbility(Shop, 'Asid')
    call UnitRemoveAbility(Shop, 'Awan')
    call UnitAddAbility(Shop, 'Aloc')

    set GoldPrice = Table.create()
    set LumberPrice = Table.create()
   
    call RemoveRect(r)
    set r = null
endfunction

endlibrary
[/jass]
回复

使用道具 举报

 楼主| 发表于 2009-2-23 20:14:54 | 显示全部楼层
Gear System
[jass]
//=========================================================================================
//===Gear System 1.8
//=========================================================================================
//Blackroot's Simple Gear System 1.8: User guide.

//Credits to Vexorian for creating vJass
//Cohadar and Weaaddar for creating GetItemCost
//Ignitedstar for bug reports
//Switch33 for bug reports.
//Thanks guys!

//=========================================================================================
//What it does:
//The idea behind this system is that by using pre-made fields in the editor, you can
//avoid having to register a huge amount of data about your item.

//Included in its features:

//The ability to auto-classify items without any scripting on your part! (You can turn this off.)

//Automatic aura applying!  (*cough* For single auras, sorry but multiple ones must be scripted :()

//The ability to restrict whole unit types from picking up certain item types (Not completely automatic)

//The ability to restrict whole unit types from picking up certain item classes!

//You can undo restrictions too! (If for example you wanted your knight to be able to
//use heavier armor at level 10, you can restrict that armor and remove the restriction
//when the unit hits level 10

//Automaticaly limit the number of an item class to 1. (That is, 1 weapon, 1 armor,
//1 special, and 1 usable.)

//Automaticaly fit the item into a slot. (Based on constants.)

//How it works:
//This system works by using information entered in the item fields to automatically generate
//information about your item.


//What it requires from the item fields:

//This system uses:
//Item Life to apply the spell aura.
//Item Classification to classify the type.
//Item Level to classify it's class.
//Item Can Be Sold from Merchant a boolean value to apply an aura or not based on the items life.
//All of these can be overridden with scripts.

//=========================================================================================
//What fields do I change:

//Stats - Classification:
//This controlls the behavior of the item, seperated into five groups:
//
//Artifact: Sets the item to behave as a weapon.
//Campaign: Sets the item to behave as armor.
//Permenant: Sets the item to behave as a special item.
//Powerup: Nothing special - note that registered powerups may not act normally.
//Charged: Flags the item as useable. Currently does nothing special.
//Any other field is IGNORED by this system.

//Stats - Hit Ponts:
//Applies an aura with the ID equal to the hit points MINUS 1!
//For example if I set hit points to 1 it would apply the spell aura of: 'A000'
//If I use a hit point amount of 9 it will use 'A008'
//If I use a hit point amount of 16 it will use 'A00F'

//Stats - Can be sold By Merchants:
//If true it will apply the aura given by the Hit Point amount.
//If false it will not apply the aura.

//Stats - Level:
//A special value for Restrictions. For example, say I wanted all melee weapons
//to be classified as something and all ranged weapons as something else.
//I would use Level(1) for melee and Level(2) for ranged (Could be any number, in fact.)
//Then I would call RestrictItemFromType(MeleeUnitID, 2)
//and call RestrictItemFromType(RangedUnitID, 1)

//Stats - Can be Sold To Merchants:
//If false this will turn on STAT REQUIREMENTS for the item.
//If false it will ignore the item in the stat checks.

//Stats - Gold Cost:
//Represents the amount of required STRENGTH a unit must have to use the item if
//Stats - Can be Sold to Merchants is false.

//Stats - Lumber Cost:
//Represents the amount of required AGILITY a unit must have to use the item if
//Stats - Can be Sold to Merchants is false.

//Stats - Charges:
//Represents the amount of required INTELLECT a unit must have to use the item if
//Stats - Can be Sold to Merchants is false.

//=========================================================================================
//How do I override settings?
//There are five functions to override items:
//RegisterItemFields
//RegisterItemType
//RegisterItemClass
//RegisterItemOverride
//RegisterItemRequirements

//The required fields are explained at the bottom.

//RegisterItemFields overwrites every field and requires all fields be input:
//integer ID, boolean aura, integer aurasid, integer typ, integer class

//RegisterItemType overwrites the items type classification. This is what you would input
//normally as Stats - Item Classification.
//It takes:
//integer ID, integer typ

//RegisterItemClass overwrites the items class classification. This is what you would input
//as the Item - Level field.
//It takes:
//integer ID, integer class

//RegisterItemOverride overwrites the items aura settings This is what you would input
//for the Item - Can be Sold by Merchants and Item - Life.
//It takes:
//integer ID, boolean auraon, integer SID

//Kay that's great, what the heck do I input for these fields?

//integer ID: The item's ID code, used CNTRL+D to see it in the object editor. It replaces
//the item name. Use cntrl+d again to switch that mode off :P.

//Boolean auraon: If you want the aura to be applied use true otherwise use false.

//integer sid/aurasid: The spell id you want applied. Note that this does not function the
//same as setting the life amount, this takes the raw spell ID which you get the same way
//you get item ids.

//integer typ: The items type classification. Use the following values to classify them:
//ITEM_PERMENANT        Special
//ITEM_CHARGED          Useable
//ITEM_POWERUP          Temporary
//ITEM_ARTIFACT         Weapon
//ITEM_PURCH            Use to ignore the item.
//ITEM_CAMPAIGN         Armor
//ITEM_MISC             Use to ignore the item.
//Use the values directly to input the type. for example:
//RegisterItemType(itemid, ITEM_PERMENANT)

//integer class: The items class classification. This is the special classification to
//be used for Restrictions. Any numerical value is acceptable in this field, it just
//represents a classification.


//==========================================================================================
//Adding custom requirements:

//The system supports stat requirements for both manual and automatic settings.

//To manually register stat requirements:

//Call:
//function RegisterItemRequirements takes integer ID, integer STR, integer AGI, integer INT returns nothing

//Very straightforward. Input everything it asks for and you're good.


//=========================================================================================
//What it cant do:

//Unfortunantly the system is built strictly for CUSTOM ITEMS ONLY.
//It will not work correctly if you try to use either.

//OMGWTFBBQ If I use one non-custom item my game explodes!?

//No, it will ignore any item outside it's standard range.


//=========================================================================================
//Item stat requirements.

//What are item stats requirements?

//Item stat requirements make it so heros must have certain stats before being able to pick
//an item up.

//How do I use Stat Requirements?

//Simple:

//Set the item Stats - Can be Sold to Merchants to _FALSE_ to turn stat requirements on for
//an item.
//Set the item's GOLD COST to the amount of required strength.
//Set the item's LUMBER COST to the amount of required agility.
//Set the item's CHARGES to the amount of required intellect.
//Profit.

//You can set an item's stat requirements manually, see "How do I override settings"

//NOTE: Items marked as Charged under the Stats - Classification are ignored for stat
//requirements but they CAN hold charges.

//More Notes: Items that are custom-registered will not function correctly unless both
//fields and stat requirements are input manually. You shoulden't be doing it manually
//anyways! :P


//=========================================================================================
//FAQ:

//Q: How do I use regular spells? I don't know how much life to use!
//A: You have to figure out the spell ID. Use CNTRL+D while looking at the spell to see it's ID
//When you have it's ID call this function with the ID you found:

//Q: How do I change the system settings?
//A: Down below in the global block. Read the comments before changing stuff mind you :P.

function WhatLifeToUse takes integer ID returns nothing
    call BJDebugMsg(I2S(ID - 'A000'))
endfunction


//=========================================================================================
library GearSystem initializer ItemSysInitTriggers

globals
   
    //Feel free to change these:
   
    //Item slots! Very important for you! If you can visualise a unit item slot, here's how
    //it looks from the games point of veiw:
    // 0 1
    // 2 3
    // 4 5
    //Keep this in mind when changing the slots!
   
    //Using -1 in any of these fields will make thoes items act normally.
   
    constant integer ITEM_SLOT_USEABLE = 2 //Useable slot.
    constant integer ITEM_SLOT_SPECIAL = 3 //Special slot.
    constant integer ITEM_SLOT_ARMOR = 4   //Armor slot.
    constant integer ITEM_SLOT_WEAPON = 5  //Weapon slot.
   
    //IMPORTANT! If you've changed the above change these accordingly!
    constant integer LOWEST_ITEM_SLOT = 2 //The lowest number used for the four above numbers.
    constant integer HIGHEST_ITEM_SLOT = 5 //The highest of the four.
   
     //True to auto register any item that's picked up. If this is off any item
     //that is not registered will be ignored.
     
     //If it's on it will examine the fields as usual.
    private constant boolean AUTO_REGISTER = true
   
    //Maximum number of Registered Items. Shoulden't need more then this.
    private constant integer MaxRegisteredItems = 256
   
    //If true checks if the total stats plus the additional stat make the unit eligible
    //for an item.
    private constant boolean REQUIREMENTS_INCLUDE_BONUS = true
   
   
    //Error codes. Change the text if you want to have it display something different.
    //It is recommended you do not change the integer values however.
    private constant integer ERROR_CODE_RESTRICTED = 10
    private constant string ERROR_RESTRICTED = "You are unable to posses that item."
   
    private constant integer ERROR_CODE_RESERVED = 20
    private constant string ERROR_RESERVED = "You can't put that item there!"
   
    private constant integer ERROR_CODE_STRENGTH = 30
    private constant string ERROR_STRENGTH = "You don't have enough Strength! Requires at least "
    private constant string ERROR_STRENGTH2 = " strength to equip."
   
    private constant integer ERROR_CODE_AGILITY = 40
    private constant string ERROR_AGILITY = "You don't have enough Agility! Requires at least "
    private constant string ERROR_AGILITY2 = " agility to equip."
   
    private constant integer ERROR_CODE_INTELLECT = 50
    private constant string ERROR_INTELLECT = "You don't have enough Intelligence! Requires at least "
    private constant string ERROR_INTELLECT2 = " intelligence to equip."
   
    private constant integer ERROR_CODE_REQUIREMENTS = 60
    private constant string ERROR_REQUIREMENTS = "This unit doesn't meet the item requirements."
   
    private constant integer ERROR_CODE_WRONGSLOT = 70
    private constant string ERROR_WRONGSLOT = "That item doesn't go there!"
   
    //===================================================================
    //Do not change anything below this unless you know what you're doing!
    constant integer ITEM_PERMENANT =   0 //Special
    constant integer ITEM_CHARGED   =   1 //Useable
    constant integer ITEM_POWERUP   =   2 //Temporary
    constant integer ITEM_ARTIFACT  =   3 //Weapon
    constant integer ITEM_PURCH     =   4 //Use to ignore the item.
    constant integer ITEM_CAMPAIGN  =   5 //Armor
    constant integer ITEM_MISC      =   7 //Use to ignore the item.
    constant integer ITEM_LOWEST_ID = 'I000'
    constant integer SPELL_LOWEST_ID = 'A000'
    constant integer ITEM_MOVE_ID_MIN = 852002
    constant integer ITEM_MOVE_ID_MAX = 852007
   
    private trigger gg_trg_ITEM_PICKED
    private trigger gg_trg_ITEM_MOVED
   
    private boolean debugit = false //Contrary to popular opinion, without this the game would crash :P.
   
    private ItemData array RegisteredItems[MaxRegisteredItems]
   
    //=====================================================================================
    //Restriction Globals
    //Maximum number of restrictions. This is probably more then anyone would even want.
    //Set this to 0 if you dont want to use restrictions.
    private constant integer MaxRegisteredRestrictions = 256
   
    //Restricted globals. Not literally :P - Woulden't suggest changing.
    private Restricted array RestrictedIds[MaxRegisteredRestrictions]
    private integer RestrictedCounter = 0
    private integer array Unrestricted
    private integer UnrestrictedCounter = 0
   
    //=====================================================================================
    //Stat Reqs
   
    private constant player  BuyerPlayer = Player(15)
    private constant integer ShopTypeId = 'nshe'
    private constant integer maxcost = 50000
    private integer LAST_REQUIRED_STAT = 0
   
    private unit Shop = null
   
    private rect ShopArea
   
    integer LAST_GOLD_COST = 0
    integer LAST_WOOD_COST = 0
endglobals

//=========================================================================================
//===CONSTANT/MISC FUNCTIONS
//=========================================================================================

constant function IsItemWeapon takes integer itype returns boolean
    return itype == ITEM_ARTIFACT
endfunction

constant function IsItemArmor takes integer itype returns boolean
    return itype == ITEM_CAMPAIGN
endfunction

constant function IsItemUseable takes integer itype returns boolean
    return itype == ITEM_CHARGED
endfunction

constant function IsItemTemporary takes integer itype returns boolean
    return itype == ITEM_POWERUP
endfunction

constant function IsItemSpecial takes integer itype returns boolean
    return itype == ITEM_PERMENANT
endfunction

constant function GetAuraId takes integer lf returns integer
    return SPELL_LOWEST_ID + lf - 1
endfunction

private function H2I takes handle h returns integer
    return h
    return 0
endfunction

//=========================================================================================
//===ITEM DATA FUNCTIONS
//=========================================================================================

struct ItemData
    boolean sell
    boolean pawn
    integer life
    integer type
    integer id
    integer level
    integer gold
    integer wood
    integer charges
endstruct

function GetItemData takes integer ID returns ItemData
    if(RegisteredItems[ID - ITEM_LOWEST_ID] == 0)then
        return -1
    endif
   
    return RegisteredItems[ID - ITEM_LOWEST_ID]
endfunction

function RemoveTheItem takes nothing returns nothing
    call RemoveItem(GetEnumItem())
endfunction

//Although it belongs to the Stat system it is required here.
function GetItemGoldCost takes integer id returns integer
    if(GetItemData(id) != -1)then
        set LAST_GOLD_COST = GetItemData(id).gold
        set LAST_WOOD_COST = GetItemData(id).wood
        return LAST_GOLD_COST
    endif

    call SetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_GOLD,   maxcost)
    call SetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_LUMBER, maxcost)
    call AddItemToStock(Shop, id, 1, 1)
    call IssueNeutralImmediateOrderById(BuyerPlayer, Shop, id)
    call RemoveItemFromStock(Shop, id)
    call EnumItemsInRect(ShopArea, null, function RemoveTheItem)
    set LAST_GOLD_COST  = maxcost - GetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_GOLD)
    set LAST_WOOD_COST  = maxcost - GetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_LUMBER)
    return LAST_GOLD_COST
endfunction

function EvaluateItemData takes integer ID returns ItemData
    local ItemData itd = ItemData.create()
    local item t = CreateItem(ID, 0, 0)
   
    set itd.sell = IsItemIdSellable(ID)
    set itd.life = R2I(GetWidgetLife(t))
    set itd.type = H2I(GetItemType(t))
    set itd.id = ID
    set itd.level = GetItemLevel(t)
    set itd.charges = GetItemCharges(t)
    set itd.pawn = IsItemIdPawnable(ID)
    set itd.gold = GetItemGoldCost(ID)
    set itd.wood = LAST_WOOD_COST
   
    call RemoveItem(t)
    set t = null
    return itd
endfunction

//=========================================================================================
//===Registration Functions
//=========================================================================================

function RegisterItem takes integer ID returns nothing
    local ItemData itd
   
    if(ID - ITEM_LOWEST_ID > MaxRegisteredItems or ID - ITEM_LOWEST_ID < 0)then
        return
    endif
    set itd = EvaluateItemData(ID)
   
    set RegisteredItems[ID - ITEM_LOWEST_ID] = itd
endfunction

function RegisterItemOverride takes integer ID, boolean aura, integer sid returns nothing
    local ItemData itd = RegisteredItems[ID - ITEM_LOWEST_ID]
   
    if(ID - ITEM_LOWEST_ID > MaxRegisteredItems or ID - ITEM_LOWEST_ID < 0)then
        return
    endif
   
    if(GetItemData(itd) == -1)then
        set itd = ItemData.create()
    endif
   
    set itd.id = ID
    set itd.sell = aura
    set itd.life = sid
   
    set RegisteredItems[ID - ITEM_LOWEST_ID] = itd
endfunction

function RegisterItemClass takes integer ID, integer class returns nothing
    local ItemData itd = RegisteredItems[ID - ITEM_LOWEST_ID]
   
    if(ID - ITEM_LOWEST_ID > MaxRegisteredItems or ID - ITEM_LOWEST_ID < 0)then
        return
    endif
   
    if(GetItemData(itd) == -1)then
        set itd = ItemData.create()
    endif
    set itd.id = ID
    set itd.level = class
    set RegisteredItems[ID - ITEM_LOWEST_ID] = itd
endfunction

function RegisterItemType takes integer ID, integer typ returns nothing
    local ItemData itd = RegisteredItems[ID - ITEM_LOWEST_ID]
   
    if(ID - ITEM_LOWEST_ID > MaxRegisteredItems or ID - ITEM_LOWEST_ID < 0)then
        return
    endif
   
    if(GetItemData(itd) == -1)then
        set itd = ItemData.create()
    endif
    set itd.id = ID
    set itd.type = typ
    set RegisteredItems[ID - ITEM_LOWEST_ID] = itd
endfunction

function RegisterItemFields takes integer ID, boolean aura, integer aurasid, integer typ, integer class returns nothing
    local ItemData itd = RegisteredItems[ID - ITEM_LOWEST_ID]
   
    if(ID - ITEM_LOWEST_ID > MaxRegisteredItems or ID - ITEM_LOWEST_ID < 0)then
        return
    endif
   
    if(GetItemData(itd) == -1)then
        set itd = ItemData.create()
    endif
   
    set itd.id = ID
    set itd.sell = aura
    set itd.life = aurasid
    set itd.type = typ
    set itd.level = class
   
    set RegisteredItems[ID - ITEM_LOWEST_ID] = itd
endfunction

function RegisterItemRequirements takes integer ID, integer STR, integer AGI, integer INT returns nothing
    local ItemData itd = RegisteredItems[ID - ITEM_LOWEST_ID]
   
    if(ID - ITEM_LOWEST_ID > MaxRegisteredItems or ID - ITEM_LOWEST_ID < 0)then
        return
    endif
   
    if(GetItemData(itd) == -1)then
        set itd = ItemData.create()
    endif
   
    set itd.id = ID
    set itd.gold = STR
    set itd.wood = AGI
    set itd.charges = INT
   
    set RegisteredItems[ID - ITEM_LOWEST_ID] = itd
endfunction

function IsItemRegistered takes integer ID returns boolean
    if(RegisteredItems[ID - ITEM_LOWEST_ID] == 0)then
        return false
    endif
    return true
endfunction

//=========================================================================================
//===HANDLER FUNCTIONS
//=========================================================================================

private function PickupError takes player p, integer ec, integer misc returns nothing
    if(ec == ERROR_CODE_RESTRICTED)then
        call DisplayTimedTextToPlayer(p, 0.52, -1.00, 2.00, "|cffffcc00"+ERROR_RESTRICTED+"|r" )
    elseif(ec == ERROR_CODE_RESERVED)then
        call DisplayTimedTextToPlayer(p, 0.52, -1.00, 2.00, "|cffffcc00"+ERROR_RESERVED+"|r" )   
    elseif(ec == ERROR_CODE_STRENGTH)then
        call DisplayTimedTextToPlayer(p, 0.52, -1.00, 2.00, "|cffffcc00"+ERROR_STRENGTH+I2S(misc)+ERROR_STRENGTH2+"|r" )      
    elseif(ec == ERROR_CODE_AGILITY)then
        call DisplayTimedTextToPlayer(p, 0.52, -1.00, 2.00, "|cffffcc00"+ERROR_AGILITY+I2S(misc)+ERROR_AGILITY2+"|r" )      
    elseif(ec == ERROR_CODE_INTELLECT)then
        call DisplayTimedTextToPlayer(p, 0.52, -1.00, 2.00, "|cffffcc00"+ERROR_INTELLECT+I2S(misc)+ERROR_INTELLECT2+"|r" )      
    elseif(ec == ERROR_CODE_REQUIREMENTS)then
        call DisplayTimedTextToPlayer(p, 0.52, -1.00, 2.00, "|cffffcc00"+ERROR_REQUIREMENTS+"|r" )         
    elseif(ec == ERROR_CODE_WRONGSLOT)then
        call DisplayTimedTextToPlayer(p, 0.52, -1.00, 2.00, "|cffffcc00"+ERROR_WRONGSLOT+"|r" )        
    endif
endfunction

function GetItemSlot takes integer Id returns integer
    if(IsItemWeapon(Id))then
        return ITEM_SLOT_WEAPON
    elseif(IsItemArmor(Id))then
        return ITEM_SLOT_ARMOR
    elseif(IsItemSpecial(Id))then
        return ITEM_SLOT_SPECIAL
    elseif(IsItemUseable(Id))then
        return ITEM_SLOT_USEABLE
    endif
   
    return -1
endfunction

function GetItemCType takes integer Id returns integer
    if(IsItemWeapon(Id))then
        return ITEM_ARTIFACT
    elseif(IsItemArmor(Id))then
        return ITEM_CAMPAIGN
    elseif(IsItemSpecial(Id))then
        return ITEM_PERMENANT
    elseif(IsItemUseable(Id))then
        return ITEM_POWERUP
    elseif(IsItemTemporary(Id))then
        return ITEM_CHARGED
    endif
    return -1
endfunction

function RemoveItemFromSlot takes unit u, integer slot returns nothing
    local item i = UnitRemoveItemFromSlot(u, slot)
    local integer ID = GetItemTypeId(i)
   
    if(RegisteredItems[ID - ITEM_LOWEST_ID].sell == true)then
        call UnitRemoveAbility(u, GetAuraId(RegisteredItems[ID - ITEM_LOWEST_ID].life))
    endif
endfunction

function IsRestricted takes integer unitid, integer level, integer itemclass returns boolean
    local integer I = 0
   
    if(RestrictedCounter == 0)then
        return false
    endif
   
    loop
        if(RestrictedIds.unitid == unitid)then
            if(RestrictedIds.class == true)then
                if(itemclass == RestrictedIds.ri)then
                    return true
                endif
            elseif(RestrictedIds.ri == level)then
                return true
            endif
        endif
        exitwhen(I == RestrictedCounter)
        set I = I + 1
    endloop
   
    return false
endfunction

function WhereIsItem takes unit u, item I returns integer
    local integer x = 0
    local item s
   
    loop
        set s = UnitItemInSlot(u, x)
        if(s == I)then
            return x
        endif
        exitwhen(x == 5)
        set x = x + 1
    endloop
    return -1
endfunction

function UnitMeetsReqs takes unit u, integer str, integer agi, integer int returns integer
    if(IsHeroUnitId(GetUnitTypeId(u)) == false)then
        return ERROR_CODE_REQUIREMENTS
    endif
   
    if(GetHeroStr(u, REQUIREMENTS_INCLUDE_BONUS) < str)then
        set LAST_REQUIRED_STAT = str
        return ERROR_CODE_STRENGTH
    elseif(GetHeroAgi(u, REQUIREMENTS_INCLUDE_BONUS) < agi)then
        set LAST_REQUIRED_STAT = agi
        return ERROR_CODE_AGILITY
    elseif(GetHeroInt(u, REQUIREMENTS_INCLUDE_BONUS) < int)then
        set LAST_REQUIRED_STAT = int
        return ERROR_CODE_INTELLECT
    endif
    return 0
endfunction

//=========================================================================================
//===MAIN HANDLER
//=========================================================================================

function UnitAttainsItem takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local item I = GetManipulatedItem()
    local integer ID = GetItemTypeId(I)
    local ItemData itd = RegisteredItems[ID - ITEM_LOWEST_ID]
    local integer fslot = WhereIsItem(u, I)
    local integer slot = -1
   
    if(debugit == true)then
        set debugit = false
        return
    else
        set debugit = true
    endif

    if(AUTO_REGISTER == true)then
        if(itd == 0)then
            call RegisterItem(ID)
            set itd = GetItemData(ID)
            if(itd == -1)then
                return
            endif
        endif
    else
        if(itd == 0)then
            return
        endif
    endif
   
    set slot = GetItemSlot(itd.type)
   
    //If the unit cannot use the item, create a new one under it and throw an error.
    if(IsRestricted(GetUnitTypeId(u), itd.level, GetItemCType(itd.type)))then
        call RemoveItem(I)
        set I = null
        call CreateItem(ID, GetUnitX(u), GetUnitY(u))
        call PickupError(GetOwningPlayer(u), ERROR_CODE_RESTRICTED, 0)
        set debugit = false
        return
    endif
   
    //If the item is put in a slot it doesn't belong in, drop the item and throw an error.
    if(slot == -1)then
        if(fslot >= LOWEST_ITEM_SLOT and fslot <= HIGHEST_ITEM_SLOT)then
            call UnitDropItemPoint(u, I, GetUnitX(u), GetUnitY(u))
            call PickupError(GetOwningPlayer(u), ERROR_CODE_RESERVED, 0)
        endif
        set debugit = false
        return
    endif
   
    call RemoveItem(I)
    set I = null
   
    if(itd.pawn == false)then
        set fslot = UnitMeetsReqs(u, itd.gold, itd.wood, itd.charges)
        if(fslot != 0)then
            call CreateItem(ID, GetUnitX(u), GetUnitY(u))
            call PickupError(GetOwningPlayer(u), fslot, LAST_REQUIRED_STAT)
            set debugit = false
            return
        endif
    endif

    set I = UnitItemInSlot(u, slot)
   
    //If the unit posses an item in the slot you want, force it to be dropped.
    if(I != null)then
        call RemoveItemFromSlot(u, slot)
    endif
   
    //If the item is not charged then continue. This is for the stat system.
    if(itd.type != ITEM_CHARGED)then
        call UnitAddItemToSlotById(u, ID, slot)
        call SetItemCharges(UnitItemInSlot(u, slot), 0)
    else
        call UnitAddItemToSlotById(u, ID, slot)
    endif
   
    if(itd.sell == true)then
        call UnitAddAbility(u, GetAuraId(itd.life))
    endif
   
    set debugit = false
endfunction

//=========================================================================================
//===RESERVE SLOT SYSTEM
//=========================================================================================

function ReturnItemToSlot takes unit u, item I, integer slot, integer rslot returns boolean
    local integer typ = GetItemTypeId(I)
    local item is = UnitItemInSlot(u, rslot)
    local ItemData itd
   
    call BJDebugMsg(I2S(slot) + " " + I2S(rslot))
   
    if(slot == rslot)then
        return false
    elseif(slot < LOWEST_ITEM_SLOT and rslot < LOWEST_ITEM_SLOT)then
        return false
    endif
   
    call RemoveItem(I)
    set I = null
   
    if(is != null)then
        set itd = GetItemData(GetItemTypeId(is))
        call RemoveItem(is)
        set is = null
        call UnitAddItemToSlotById(u, itd.id, GetItemSlot(itd.type))
        call UnitAddItemToSlotById(u, typ, rslot)
        return true
    endif
    call UnitAddItemToSlotById(u, typ, slot)   
    return true
endfunction

function UnitMovesItem takes unit u, item I, integer slot returns nothing
    local integer ID = GetItemTypeId(I)
    local ItemData itd = GetItemData(ID)
    local integer is = GetItemSlot(ID)
   
    if(ReturnItemToSlot(u, I, slot, GetItemSlot(itd.type)))then
        call PickupError(GetOwningPlayer(u), ERROR_CODE_RESERVED, 0)            
    endif
    return
endfunction

function UnitOrderHandler takes nothing returns nothing
    local integer oid = GetIssuedOrderId() - ITEM_MOVE_ID_MIN
    local unit u = GetTriggerUnit()
    local item I = GetOrderTargetItem()
   
    if(oid >= 0 and oid <= 5)then
        call UnitMovesItem(u, I, oid)   
    endif
endfunction

//=========================================================================================
//===RESTRICTIONS
//=========================================================================================

struct Restricted
    integer unitid
    integer ri
    boolean class = false
endstruct

function RestrictIdFromClass takes integer unitid, integer ri returns nothing
    local Restricted rs = Restricted.create()
   
    set rs.unitid = unitid
    set rs.ri = ri
    set rs.class = true
   
    if(UnrestrictedCounter > 0)then
        set RestrictedIds[Unrestricted[UnrestrictedCounter]] = rs
        set UnrestrictedCounter = UnrestrictedCounter - 1
    else
        set RestrictedIds[RestrictedCounter] = rs
        set RestrictedCounter = RestrictedCounter + 1
    endif
endfunction

function RestrictIdFromType takes integer unitid, integer ri returns nothing
    local Restricted rs = Restricted.create()
    set rs.unitid = unitid
    set rs.ri = ri
   
    if(UnrestrictedCounter > 0)then
        set RestrictedIds[Unrestricted[UnrestrictedCounter]] = rs
        set UnrestrictedCounter = UnrestrictedCounter - 1
    else
        set RestrictedIds[RestrictedCounter] = rs
        set RestrictedCounter = RestrictedCounter + 1
    endif
endfunction

function StopRestrictionOnClass takes integer unitid, integer ri returns nothing
    local integer I = 0
   
    loop
        if((unitid == RestrictedIds.unitid) and (ri == RestrictedIds.ri) and (RestrictedIds.class == true))then
            call RestrictedIds.destroy()
            set RestrictedIds = RestrictedIds[RestrictedCounter]
            set RestrictedCounter = RestrictedCounter - 1
            
            set Unrestricted[UnrestrictedCounter] = I
            set UnrestrictedCounter = UnrestrictedCounter + 1
        endif
        exitwhen(I == RestrictedCounter)
        set I = I + 1
    endloop
endfunction

function StopRestrictionOnType takes integer unitid, integer ri returns nothing
    local integer I = 0
   
    loop
        if((unitid == RestrictedIds.unitid) and (ri == RestrictedIds.ri))then
            call RestrictedIds.destroy()
            set RestrictedIds = RestrictedIds[RestrictedCounter]
            set RestrictedCounter = RestrictedCounter - 1
            
            set Unrestricted[UnrestrictedCounter] = I
            set UnrestrictedCounter = UnrestrictedCounter + 1
        endif
        exitwhen(I == RestrictedCounter)
        set I = I + 1
    endloop
endfunction

//=========================================================================================
//===STAT SYSTEM
//=========================================================================================

private function InitStatReqs takes nothing returns nothing
    local rect r = GetPlayableMapRect()
    set Shop = CreateUnit(BuyerPlayer, ShopTypeId, GetRectMinX(r), GetRectMaxY(r), 0)
   
    call ShowUnit(Shop, false)
    call UnitAddAbility(Shop, 'Asid')
    call UnitRemoveAbility(Shop, 'Awan')
    call UnitAddAbility(Shop, 'Aloc')
   
    set ShopArea = Rect(GetUnitX(Shop) - 64, GetUnitY(Shop) - 64, GetUnitX(Shop) + 64, GetUnitY(Shop) + 64)
   
    call RemoveRect(r)
    set r = null
endfunction

//=========================================================================================
//===INITIALIZER
//=========================================================================================

function ItemSysInitTriggers takes nothing returns nothing
    set gg_trg_ITEM_PICKED = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_ITEM_PICKED, EVENT_PLAYER_UNIT_PICKUP_ITEM)
    call TriggerAddAction(gg_trg_ITEM_PICKED, function UnitAttainsItem)
   
    set gg_trg_ITEM_MOVED = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_ITEM_MOVED, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
    call TriggerAddAction(gg_trg_ITEM_MOVED, function UnitOrderHandler)
   
    call InitStatReqs()
endfunction

endlibrary
[/jass]
回复

使用道具 举报

 楼主| 发表于 2009-2-25 22:13:01 | 显示全部楼层
[jass]
globals
//Color Strings
constant string cred = "|c00FF0000"
constant string cblue = "|c000080C0"
constant string cgold = "|c00808040"
constant string cpurp = "|c00BF00A4"
constant string cyell = "|c00FFFF00"
constant string cend = "|r"

//Integer Array for Dual Wielding Classes
integer array DWC
integer DWC_count = 0


//Multiboard
multiboard array INVENTORY_MB
real mb_slot_width = 10.0

//Array to track our heros
unit array Hero


//Item System Variables
integer CurrClass = 0               //Variable to track current equiping character's class
string ItemError=""                 //Error message string
ItemStruct item_to_equip            //Temporary ItemStruct to house information
Equipment array hero_equipment[10]  //An array of our hero's equipment

//Equipment Slots
string array IS_SLOT
integer SLOT_COUNT


integer       itemcount = 0          //Keeps track of how many items are in our array
ItemStruct array itemlist[1000]     //Houses the array of our structs, each item.

string equipstring = "e"



endglobals




library ItemCreation

struct ItemStruct
integer item_id
string item_name
string item_type
integer slot
//Requirements
integer who
integer level
integer str_r
integer agi_r
integer int_r
//Bonuses
integer str
integer agi
integer int
integer dmg
integer armor
integer hp
integer mp

string model

private method onDestroy takes nothing returns nothing
set .item_id = 0
set .item_name = ""
set .item_type = ""
set .slot = 0
set .who=0
set .level=0
set .str_r=0
set .agi_r=0
set .int_r=0
set .str=0
set .agi=0
set .int=0
set .dmg=0
set .armor=0
set .hp=0
set .mp=0
set .model = ""
endmethod

endstruct

//A static method for creation cannot be used, too many elements are taken in and it overloads that method
public function CreateCustomItem takes integer id, integer slot, string itype, integer who, integer level, integer str_r, integer agi_r,integer int_r, integer str, integer agi, integer int, integer dmg, integer armor, integer hp, integer mp, string model returns nothing
local ItemStruct is = ItemStruct.create()
local item it = CreateItem(id,0,0)
local string temp = GetItemName(it)
call RemoveItem(it)

set is.item_id = id
set is.item_name = temp
set is.item_type = itype
set is.slot = slot
set is.who = who
set is.level = level
set is.str_r = str_r
set is.agi_r = agi_r
set is.int_r = int_r
set is.str = str
set is.agi = agi
set is.int = int
set is.dmg = dmg
set is.armor = armor
set is.hp = hp
set is.mp = mp
set is.model = model

set it = null
set itemlist[itemcount] = is
set itemcount = itemcount + 1
endfunction
endlibrary


library ItemSystem requires BonusMod

//Character's equipment is an array of 8 ItemStructs
struct Equipment
ItemStruct array List[9]//9 means we want 9 slots, this actually means the array slots are 0 through 8
endstruct

//Checks our database of items for itemid
//If found it returns the array index
//If not found it returns -1
function FindItem takes integer itemid returns ItemStruct
local integer i = 0
loop
exitwhen i>itemcount
if itemid==itemlist.item_id then
return itemlist
endif
set i = i + 1
endloop
return -1
endfunction

function AddClassToDWC takes integer i returns nothing
set DWC[DWC_count]=i
set DWC_count=DWC_count+1
endfunction

function RemovesZeros takes integer i returns string
if i==0 then
return " "
endif
return I2S(i)
endfunction

function AddSlot takes string str returns nothing
set SLOT_COUNT = SLOT_COUNT + 1
set IS_SLOT[SLOT_COUNT] = str
endfunction


function GetSlotName takes integer in returns string str
return IS_SLOT[in]
endfunction

function FindSlot takes string str, integer first returns integer
local integer i = 1
loop
exitwhen i>SLOT_COUNT
if ((IS_SLOT==str) and not(first==i) ) then
return i
endif
set i = i + 1
endloop
return -1
endfunction

function ClearEquipMultiboard takes player p returns nothing
local integer idx = GetConvertedPlayerId(p)
local multiboard mb = INVENTORY_MB[idx]
local integer i = 1
local integer j = 4
loop
exitwhen i>8
call MultiboardSetItemIconBJ( mb, 2, i+1, emptyslot )
call MultiboardSetItemValueBJ( mb, 3, i+1, "|c00808080-"+IS_SLOT+"-|r" )
loop
exitwhen j>12
call MultiboardSetItemValueBJ(mb, j, i+1, " ")
set j = j + 1
endloop
set i = i+1
endloop

set mb = null
endfunction

function FlushEquipment takes player p returns nothing
local integer idx = GetPlayerId(p)+1
local Equipment e = hero_equipment[idx]
local integer i = 1
local string str
local multiboard mb = INVENTORY_MB[idx]
local integer it = e.List

loop
exitwhen i>9
set e.List=0
set i = i +1
call TriggerSleepAction(.1)
endloop

call ClearEquipMultiboard(p)

endfunction

function ClassSetup takes unit u returns nothing
local integer ut = GetUnitTypeId(u)
set CurrClass=-1
if ut == class1 then
set CurrClass=1
elseif ut==class2 then
set CurrClass=2
elseif ut==class3 then
set CurrClass=4
elseif ut==class4 then
set CurrClass=8
elseif ut==class5 then
set CurrClass=16
elseif ut==class6 then
set CurrClass=32
elseif ut==class7 then
set CurrClass=64
elseif ut==class8 then
set CurrClass=128
elseif ut==class9 then
set CurrClass=256
elseif ut==class10 then
set CurrClass=512
elseif ut==class11 then
set CurrClass=1024
elseif ut==class12 then
set CurrClass=2048
elseif ut==class13 then
set CurrClass=4096
elseif ut==class14 then
set CurrClass=8192
endif
endfunction

function ItemSystemClassCheck takes integer hero, integer permissions returns boolean
local integer i = 16384
local integer b = 14
loop
set i = i / 2
set b = b - 1
exitwhen b < 0
if permissions >= i then
if i == hero then
return true
endif
set permissions = permissions - i
endif
endloop
return false
endfunction

function ItemClassCheck takes unit u, ItemStruct is returns string
if not(ItemSystemClassCheck(CurrClass, is.who)) then
return "Your class cannot use that."
endif
return ""
endfunction

function ItemStatCheck takes unit u, ItemStruct is returns string
local integer lvl = GetUnitLevel(u)
local integer s = GetHeroStr(u, true)
local integer a = GetHeroAgi(u, true)
local integer i = GetHeroInt(u, true)
local boolean b = false
if (lvl < is.level) then
return "You need to be level "+I2S(is.level)+" to use that item."
elseif s <is.str_r then
return "You need "+I2S(is.str_r - s)+" more strength to use that item."
elseif a <is.agi_r then
return "You need "+I2S(is.agi_r - a)+" more agility to use that item."
elseif i <is.int_r then
return "You need "+I2S(is.int_r - i)+" more intelligence to use that item."
endif
return ""
endfunction

function DualWeildCheck takes unit u returns boolean
local boolean b = false
local integer ut = GetUnitTypeId(u)
local integer i = 0
loop
exitwhen i > DWC_count
if ut==DWC then
return true
endif
set i = i + 1
endloop
return false
endfunction

function ItemSlotCheck takes ItemStruct is, unit u returns integer
local Equipment e = hero_equipment[GetPlayerId(GetOwningPlayer(u)) + 1]
local integer j = 1
loop
exitwhen j > SLOT_COUNT
if is.slot==j then //Loop variable found our slot
if is.item_type == "e" then //Item is of standard equipment type
if e.List[is.slot].item_id==0 then // Slot is empty
return is.slot
else
//Slot is not empty
//Check if there is another slot with the same name
//Example: Accessory is slot 5 and 6. The loop sees there is something in slot 5
//We cycle through our list to see if there is another slot titled "Accessory"
if e.List[FindSlot(IS_SLOT[is.slot], is.slot)]==0 then //We found another empty slot
return FindSlot(IS_SLOT[is.slot], is.slot) //Return the empty spot
endif
return -1
endif

elseif is.item_type == "1h" then//One handed weapon

//Checks if a 2 handed weapon is equip
if e.List[FindSlot(IS_SLOT[is.slot],0)].item_type == "2h" then //Finds the first shared slot, if its 2h, then we can't use it
return -1
elseif e.List[FindSlot(IS_SLOT[is.slot],(FindSlot(IS_SLOT[is.slot],is.slot)))].item_type == "2h" then //SHOULD NEVER HAPPEN, but does the same as above but checks the other hand
call BJDebugMsg("ItemSlotCheck - 1h condition, 2h error")
return -1
endif


if DualWeildCheck(u) then
if not(e.List[FindSlot(IS_SLOT[is.slot],0)].item_type=="1h") then//If first slot is open, take it
return e.List[FindSlot(IS_SLOT[is.slot],0)]
elseif not(e.List[FindSlot(IS_SLOT[is.slot],FindSlot(IS_SLOT[is.slot],0))].item_type=="1h") then//If second slot is open, take it
return e.List[FindSlot(IS_SLOT[is.slot],FindSlot(IS_SLOT[is.slot],0))]
else
return -1//Neither slot is open
endif
else
//If either slot is already 1h, then you cannot dual wield.
if not(e.List[FindSlot(IS_SLOT[is.slot],0)].item_type=="1h") and not(e.List[FindSlot(IS_SLOT[is.slot],FindSlot(IS_SLOT[is.slot],0))].item_type=="1h") then //If the first slot and second slot are both empty
return is.slot
else
return -1
endif
endif

elseif is.item_type == "2h" then //2 handed weapon
//Check if the first slot and second slots have nothing stored in them
//If nothing is stored in there return the first slot
if ((e.List[FindSlot(IS_SLOT[is.slot],0)].item_id == 0) and (e.List[FindSlot(IS_SLOT[is.slot], FindSlot(IS_SLOT[is.slot], 0))].item_id == 0)) then
//call BJDebugMsg("2h -- Found = "+I2S(FindSlot(IS_SLOT, 0))
return FindSlot(IS_SLOT[is.slot], 0)
else
return -1
endif
endif
endif
set j = j + 1
endloop
return -1
endfunction

function UpdateMultiboardTotals takes integer idx returns nothing
local integer i = 0
loop
exitwhen i > 6
call MultiboardSetItemValueBJ(INVENTORY_MB[idx], (i+4), 10, cgold+RemovesZeros((getBonus(Hero[idx], i)))+cend)
set i = i + 1
endloop
endfunction

function UpdateMultiboardItemSystem takes integer idx, integer slot, item it, boolean add returns nothing
local multiboard mb = INVENTORY_MB[idx]
local integer i = 1
if add then
call MultiboardSetItemIconBJ( mb, 2, slot+1, item_to_equip.model )
call MultiboardSetItemValueBJ( mb, 3, slot+1, GetItemName(it) )
call MultiboardSetItemValueBJ( mb, 4, slot+1, RemovesZeros(item_to_equip.dmg))
call MultiboardSetItemValueBJ( mb, 5, slot+1, RemovesZeros(item_to_equip.armor))
call MultiboardSetItemValueBJ( mb, 6, slot+1, RemovesZeros(item_to_equip.hp))
call MultiboardSetItemValueBJ( mb, 7, slot+1, RemovesZeros(item_to_equip.mp))
call MultiboardSetItemValueBJ( mb, 8, slot+1, RemovesZeros(item_to_equip.str))
call MultiboardSetItemValueBJ( mb, 9, slot+1, RemovesZeros(item_to_equip.agi))
call MultiboardSetItemValueBJ( mb, 10, slot+1, RemovesZeros(item_to_equip.int))

//If it is a 2 handed weapon it greys out slot 2
if item_to_equip.item_type=="2h" then
call MultiboardSetItemValueBJ( mb, 3, FindSlot(GetSlotName(item_to_equip.slot), item_to_equip.slot)+1, "|c00808080"+GetItemName(it)+"|r" )
endif

else
call MultiboardSetItemIconBJ( mb, 2, slot+1, emptyslot )
set i = 1
loop
exitwhen i > 9
call MultiboardSetItemValueBJ( mb, (i+3), slot+1, " " )
set i = i + 1
endloop

if item_to_equip.slot>0 then
call MultiboardSetItemValueBJ( mb, 3, slot+1, "|c00808080-"+IS_SLOT[slot]+"-|r" )
endif

if item_to_equip.slot==8 then
call MultiboardSetItemValueBJ( mb, 3, slot+2, "|c00808080-Right Hand-|r" )
endif

endif

call UpdateMultiboardTotals(idx)

set mb = null
endfunction

function ItemAddToChar takes unit u, item i, ItemStruct is, integer slot returns nothing
local integer idx = GetPlayerId(GetOwningPlayer(u)) + 1
call UpdateMultiboardItemSystem(idx,slot, i,true)
set hero_equipment[idx].List[slot] = is
call RemoveItem(i)
endfunction

function ItemUpdateChar takes unit u, integer i returns nothing
call addBonus(i*item_to_equip.dmg,u,0) //Set Damage
call addBonus(i*item_to_equip.armor,u,1) //Set Armor
call addBonus(i*item_to_equip.hp,u,2) //Set HP
call addBonus(i*item_to_equip.mp,u,3) //Set MP
call addBonus(i*item_to_equip.str,u,4) //Set Str
call addBonus(i*item_to_equip.agi,u,5) //Set Agi
call addBonus(i*item_to_equip.int,u,6) //Set Int
endfunction

//Needs a udg_SimError global sound variable
function SimError takes player ForPlayer, string msg returns nothing
if udg_SimError==null then
set udg_SimError=CreateSoundFromLabel( "InterfaceError",false,false,false,10,10)
endif
if (GetLocalPlayer() == ForPlayer) then
//call ClearTextMessages()
call DisplayTimedTextToPlayer( ForPlayer, 0.52, -1.00, 2.00, "|cffffcc00"+msg+"|r" )
call StartSound( udg_SimError )
endif
endfunction

function ItemFinish takes unit u, string str returns nothing
call SimError(GetOwningPlayer(u), str)
endfunction

function RemoveAnItem takes unit u, integer i returns nothing
local integer idx = GetPlayerId(GetOwningPlayer(u)) + 1
local Equipment e = hero_equipment[idx]
local ItemStruct is = e.List

//If there is no item
if is.item_id<1 then
call SimError(GetOwningPlayer(u), "There is no item in that slot.")
return
endif

call ItemUpdateChar(u,-1)
call UpdateMultiboardItemSystem(idx,i, null, false)

set bj_lastCreatedItem = CreateItem(is.item_id, GetUnitX(u), GetUnitY(u))
set e.List=0
call SimError(GetOwningPlayer(u), "Dropping: "+GetItemName(bj_lastCreatedItem))
endfunction

function EquipAnItem takes unit u, item i returns boolean
local integer it = GetItemTypeId(i)
local ItemStruct is = FindItem(it)
local string str = ""
if (is == -1) then
call SimError(GetOwningPlayer(u), "Error: Item not in database")
return false
endif

call ClassSetup(u)

set item_to_equip = is

//call ItemSetup(it)

//Checks if our class can use it
//Checks if our level, and attr allow equiping
set str = ItemClassCheck(u, is)
if not(str=="") then
call ItemFinish(u, str)
return false
endif

set str = ItemStatCheck(u, is)
if not(str=="") then
call ItemFinish(u, str)
return false
endif



//Checks slot avaliability
if ItemSlotCheck(it,u) == -1 then
call ItemFinish(u, "Equipment slot unavailable.")
else
call ItemUpdateChar(u, 1)
call ItemAddToChar(u,i, item_to_equip, ItemSlotCheck(it,u))
set ItemError="Equipping:"+GetItemName(i)
return true
endif


return false
endfunction



function ItemSystemInit takes nothing returns nothing
endfunction

endlibrary

//====================================================================== =====

[/jass]
回复

使用道具 举报

 楼主| 发表于 2009-3-3 20:45:25 | 显示全部楼层
RCCS v W
[jass]
constant function H2I takes handle h returns integer
    return h
    return 0
endfunction

constant function B2I takes boolean b returns integer
    if(b)then
        return 1
    endif
    return 0
endfunction

function GetItemSlot takes unit hero, item it returns integer
    local integer i=0
    loop
        exitwhen i==6
        if(UnitItemInSlot(hero,i)==it)then
            return i
        endif
        set i=i+1
    endloop
    return -1
endfunction
function SimError takes player ForPlayer, string msg returns nothing
    local sound error=CreateSoundFromLabel( "InterfaceError",false,false,false,10,10)
        if (GetLocalPlayer() == ForPlayer) then
            call ClearTextMessages()            
                call StartSound( error )
            call DisplayTimedTextToPlayer( ForPlayer, 0.52, -1.00, 2.00, "|cffffcc00"+msg+"|r" )
        endif
        call KillSoundWhenDone(error)
    set error=null
endfunction
function AbilityGetMaxLevel takes integer abil returns integer
    local unit hero
    local integer max=GetStoredInteger(objects(),I2S(abil),"m_maxlvl")
    if(abil==0)then
        return 0
    endif
    if(max==0)then
        set hero=CreateUnit(Player(15),'hfoo',0,0,0)
        call UnitAddAbility(hero,abil)
        call SetUnitAbilityLevel(hero,abil,100)
        set max=GetUnitAbilityLevel(hero,abil)
        call StoreInteger(objects(),I2S(abil),"m_maxlvl",max)
        call RemoveUnit(hero)
        set hero=null
    endif
    return max
endfunction

function Vector_size takes string vector returns integer
    return GetStoredInteger(objects(),vector,"m_size")
endfunction

function Vector_getElem takes string vector,integer index returns integer
    return GetStoredInteger(objects(),vector,"m_a"+I2S(index))
endfunction

function Vector_setElem takes string vector,integer index, integer data returns boolean
    if(index<0 or index>=Vector_size(vector))then
        return false
    endif
    call StoreInteger(objects(),vector,"m_a"+I2S(index),data)
    return true
endfunction

function Vector_addElem takes string vector, integer data returns boolean
    local gamecache gc=objects()
    local integer size=Vector_size(vector)
    call StoreInteger(gc,vector,"m_a"+I2S(size),data)
    call StoreInteger(gc,vector,"m_size",size+1)
    return true
endfunction

function Vector_removeElem takes string vector, integer index returns integer
    local integer size=Vector_size(vector)-1
    local gamecache gc=objects()
    local integer val=GetStoredInteger(gc,vector,"m_a"+I2S(index))
    local integer i=index
    if(index<=size and index>=0)then
        loop
            exitwhen i==size
            call StoreInteger(gc,vector,"m_a"+I2S(i),GetStoredInteger(gc,vector,"m_a"+I2S(i+1)))
            set i=i+1
        endloop
        call StoreInteger(gc,vector,"m_size",size)
        call StoreInteger(gc,vector,"m_a"+I2S(size),0) //reset it to zero
    endif
    set gc=null
    return val
endfunction

function Vector_swapElems takes string vector, integer x,integer y returns nothing
    local integer i=Vector_getElem(vector,x)
    call Vector_setElem(vector,x,Vector_getElem(vector,y))
    call Vector_setElem(vector,y,i)
endfunction

function GetUniqueId takes nothing returns integer
    local gamecache gc=null
    local integer last=0
    local integer size=Vector_size("0")
    set gc=objects()
    if(size!=0)then
        return Vector_removeElem("0",size-1)
    endif
    set last=GetStoredInteger(gc,"index","index")+1
    call StoreInteger(gc,"Index","index",last)
    set gc=null
    return last
endfunction

function DestroyObject takes string object returns nothing
    call FlushStoredMission(objects(),object)
endfunction

function RecycleObject takes string object returns nothing
    if(object=="0")then
        return
    endif
    call Vector_addElem("0",S2I(object)) //recycle object type.
    call DestroyObject(object)
endfunction

function CreateVector takes nothing returns string
    return I2S(GetUniqueId())
endfunction
//==================================================================
function Node_setData takes string node,integer data returns nothing
    local gamecache gc=objects()
    call StoreInteger(gc,node,"M_data",data)
    set gc=null
endfunction

function Node_setNext takes string node,string next returns nothing
    local gamecache gc=objects()
    call StoreString(gc,node,"m_next",next)
    set gc=null
endfunction

function Node_setPred takes string node,string pred returns nothing
    local gamecache gc=objects()
    call StoreString(gc,node,"m_pred",pred)
    set gc=null
endfunction

function Node_getData takes string node returns integer
    local gamecache gc=objects()
    local integer data=GetStoredInteger(gc,node,"m_data")
    set gc=null
    return data
endfunction

function Node_getNext takes string node returns string
    local gamecache gc=objects()
    local string next=GetStoredString(gc,node,"m_next")
    set gc=null
    return next
endfunction
   
function Node_getPred takes string node returns string
    local gamecache gc=objects()
    local string pred=GetStoredString(gc,node,"m_pred")
    set gc=null
    return pred
endfunction


function CreateNode takes integer data,string next,string pred returns string
    local string this=I2S(GetUniqueId())
    local gamecache gc=objects()
    call StoreInteger(gc,this,"m_data",data)
    if (next=="this")then
        set next=this
    endif
    call StoreString(gc,this,"m_next",next)
    if(pred=="this")then
        set pred=this
    endif
    call StoreString(gc,this,"m_pred",pred)
    set gc=null
    return this
endfunction

function Queue_getTail takes string q returns string
    local gamecache gc=objects()
    local string t=GetStoredString(gc,q,"m_tail")
    set gc=null
    return t
endfunction
function Queue_getLength takes string q returns integer
    local gamecache gc=objects()
    local integer l=GetStoredInteger(gc,q,"m_length")
    set gc=null
    return l
endfunction
function Queue_getSize takes string q returns integer
    local gamecache gc=objects()
    local integer s=GetStoredInteger(gc,q,"m_size")
    set gc=null
    return s
endfunction


//Will only return the falling off tail's data field.
function Queue_Enqueue takes string q,integer data returns integer
    local gamecache gc=objects()
    local string tail=Queue_getTail(q)
    local string head=null
    local string pred=null
    local string new=null
    local integer size=Queue_getSize(q)
    local integer length=Queue_getLength(q)
    local integer ret=0
    if(tail==null)then //0 element q
        set new=CreateNode(data,"this","this")
        call StoreString(gc,q,"m_tail",new)
        call StoreInteger(gc,q,"m_size",1)
    elseif(size!=length)then
        set head=Node_getNext(tail)
        set new=CreateNode(data,head,tail)
        call Node_setNext(tail,new)
        call Node_setPred(head,new)
        call StoreInteger(gc,q,"m_size",size+1)
    else
        set head=Node_getNext(tail)
        set pred=Node_getPred(tail)
        set new=CreateNode(data,head,pred)
        call Node_setPred(head,new)
        call Node_setNext(pred,new)
        call StoreString(gc,q,"m_tail",pred)
        set ret=Node_getData(tail)
        call RecycleObject(tail)
    endif
    return ret
endfunction

function Queue_Dequeue takes string q returns integer
    local gamecache gc=objects()
    local string tail=Queue_getTail(q)
    local string head=null
    local string pred=null
    local integer ret
    if(tail==null)then
        set ret=-1
    elseif(Queue_getSize(q)==1)then //this queue has one elem
        call StoreInteger(gc,q,"m_size",0)
        set ret=Node_getData(tail)
        call RecycleObject(tail)
        call StoreString(gc,q,"m_tail",null)
    else
        set head=Node_getNext(tail)
        set pred=Node_getPred(tail)
        call StoreInteger(gc,q,"m_size",Queue_getSize(q)-1)
        set ret=Node_getData(tail)
        call Node_setNext(pred,head)
        call Node_setPred(head,pred)
        call RecycleObject(tail)
        call StoreString(gc,q,"m_tail",pred)
    endif
    return ret
endfunction
//length must be at least two.
function CreateQueue takes integer length returns string
    local string this=I2S(GetUniqueId())
    local gamecache gc=objects()
    call StoreInteger(gc,this,"m_length",length)
    call StoreInteger(gc,this,"m_size",0)
    set gc=null
    return this
endfunction
//==============================================================
function IV_capacity takes string iv returns integer
    return GetStoredInteger(objects(),iv,"m_capacity")
endfunction

function IV_getItem takes string iv,integer ix returns item
    return Vector_getElem(iv,ix)
    return null
endfunction

function IV_setItem takes string iv,integer ix,item it returns nothing
    call Vector_setElem(iv,ix,H2I(it))
endfunction

function IV_getIndexOfItem takes string iv,item it returns integer
    local integer i=0
    local integer end=Vector_size(iv)
    local integer target=H2I(it)
    loop
        exitwhen i==end
        if(Vector_getElem(iv,i)==target)then
            return i
        endif
        set i=i+1
    endloop
    return -1
endfunction

function IV_addItem takes string iv,item it returns boolean
    if(IV_capacity(iv)==0)then
        return Vector_addElem(iv,H2I(it))
    elseif(IV_capacity(iv)==Vector_size(iv))then
        return false
    else
        return Vector_addElem(iv,H2I(it))
    endif
endfunction

function IV_removeItemByIx takes string iv,integer ix returns item
    return Vector_removeElem(iv,ix)
    return null
endfunction

function IV_removeItem takes string iv,item toRemove returns boolean
    return IV_removeItemByIx(iv,IV_getIndexOfItem(iv,toRemove))!=null
endfunction

function PrintIV takes string iv returns nothing
    local integer i=0
    local integer size=Vector_size(iv)
    loop
        exitwhen i==size
        call BJDebugMsg(GetItemName(IV_getItem(iv,i)))
        set i=i+1
    endloop
endfunction

function CreateIV takes integer capacity returns string
    local string this=CreateVector()
    call StoreInteger(objects(),this,"m_capacity",capacity)
    return this
endfunction
//=========================================================================
function Hero_getState takes unit hero returns integer
    return GetStoredInteger(objects(),I2S(H2I(hero)),"m_state")
endfunction

function Hero_setState takes unit hero,integer state returns nothing
    call StoreInteger(objects(),I2S(H2I(hero)),"m_state",state)
endfunction

function Hero_getNext takes unit hero returns item
    return GetStoredInteger(objects(),I2S(H2I(hero)),"m_next")
    return null
endfunction

function Hero_getCancel takes unit hero returns item
    return GetStoredInteger(objects(),I2S(H2I(hero)),"m_cancel")
    return null
endfunction

function Hero_BlankIV takes unit hero returns string
    return GetStoredString(objects(),I2S(H2I(hero)),"m_biv")
endfunction

function Hero_IV takes unit hero returns string
    return GetStoredString(objects(),I2S(H2I(hero)),"m_iv")
endfunction

function Hero_getFree takes unit hero returns integer
    return GetStoredInteger(objects(),I2S(H2I(hero)),"m_free")
endfunction

function Hero_setFree takes unit hero,integer free returns nothing
    call StoreInteger(objects(),I2S(H2I(hero)),"M_free",free)
endfunction

function Hero_addToIV takes unit hero,item toAdd returns boolean
    local string iv=Hero_IV(hero)
    local integer i=0
    local integer free=Hero_getFree(hero)
    if(free==0)then
        return false
    else
        loop
            exitwhen i==6
            if(IV_getItem(iv,i)==null)then
                call UnitRemoveItem(hero,toAdd)
                call SetItemVisible(toAdd,false)
                call IV_setItem(iv,i,toAdd)
                call Hero_setFree(hero,free-1)
                set i=5
            endif
            set i=i+1
        endloop
    return true
    endif
endfunction
   
function Hero_removeBlanks takes unit hero returns nothing
    local integer i=0
    local integer state=Hero_getState(hero)
    local item temp=null
    call Hero_setState(hero,74)
    loop
        exitwhen i==6
        set temp=UnitItemInSlot(hero,i)
        if(GetItemTypeId(temp)==IDBlank())then
            call UnitRemoveItem(hero,temp)
            call SetItemVisible(temp,false)
        endif
        set i=i+1
    endloop
    call Hero_setState(hero,state)
    set temp=null
endfunction

function Hero_clearInv takes unit hero returns nothing
    local integer i=0
    local integer state=Hero_getState(hero)
    call Hero_setState(hero,74) //prevents drop from firing.
    loop
        exitwhen i==6
        call SetItemVisible(UnitRemoveItemFromSlot(hero,i),false)
        set i=i+1
    endloop
    call Hero_setState(hero,state)
endfunction

function Hero_swapInv takes unit hero returns nothing
    local integer i=0
    local item toIV=null
    local item toH=null
    local string hiv=Hero_IV(hero)
    local string biv=Hero_BlankIV(hero)
    local integer state=Hero_getState(hero)
    local integer free=0
    call Hero_setState(hero,74) //prevents drop from firing.
    call StoreInteger(objects(),I2S(H2I(hero)),"m_used",UnitInventoryCount(hero))
    loop
        exitwhen i==6
        set toIV=UnitRemoveItemFromSlot(hero,i)
        if(toIV==null)then
            set free=free+1
        endif
        set toH=IV_getItem(hiv,i)
        if(toH==null)then
            set toH=IV_getItem(biv,i)
        endif
        call SetItemVisible(toIV,false)
        call SetItemVisible(toH,true)
        call IV_setItem(hiv,i,toIV)
        call UnitAddItem(hero,toH)
        set i=i+1
    endloop
    set i=0
    call Hero_setFree(hero,free)
    call Hero_removeBlanks(hero)
    call Hero_setState(hero,state)
    set toIV=null
    set toH=null
endfunction

//assumes passed an empty INVed hero
// Returns the current Page indexed.
function Hero_nextPage takes unit hero,string iv,integer page,boolean droppable returns integer
    local integer i=0
    local integer limit=Vector_size(iv)
    local item temp=null
    set page=page+1
    if( ((page-1)*4)>=limit)then
        set page=1
    endif
    loop
        exitwhen i==4
        set temp=IV_getItem(iv,(page-1)*4+i)
        if(temp==null)then
            set temp=IV_getItem(Hero_BlankIV(hero),i )
        endif
        call SetItemVisible(temp,true)
        call UnitAddItem(hero,temp)
        set i=i+1
    endloop
    set temp=Hero_getNext(hero)
    call SetItemVisible(temp,true)
    call SetItemCharges(temp,page)
    call UnitAddItem(hero,temp)
    set temp=Hero_getCancel(hero)
    call UnitAddItem(hero,temp)
    call SetItemVisible(temp,true)
    call SetItemDroppable(temp,droppable)
    return page
endfunction
//===========================================================================
// Constructor:
// ===========
// There is only one constructor for hero.
// CreateHero(unit hero) turns the unit in to a Hero object. It also creates
// the internal iv and explicitly sets it size to 6.
//===========================================================================
function CreateHero takes unit hero returns unit
    local gamecache gc=objects()
    local string this=I2S(H2I(hero))
    local string iv=CreateIV(6)
    local string biv=CreateIV(6)
    local integer i=0
    local item temp=null
    call StoreString(gc,this,"m_IV",iv)
    call StoreString(gc,this,"m_BIV",biv)
    loop
        exitwhen i==6
        set temp=CreateItem(IDBlank(),0,0)
        call IV_addItem(biv,temp)
        call SetItemVisible(temp,false)
        set i=i+1
    endloop
    set temp=CreateItem(IDCancel(),0,0)
    call SetItemVisible(temp,false)
    call StoreInteger(gc,this,"m_cancel",H2I(temp))
   
    set temp=CreateItem(IDNext(),0,0)
    call SetItemVisible(temp,false)
    call StoreInteger(gc,this,"m_next",H2I(temp))
   
    call StoreInteger(gc,iv,"m_size",6)
    set gc=null
    set temp=null
    return hero
endfunction

function T_getHero takes timer t returns unit
    return GetStoredInteger(objects(),I2S(H2I(t)),"m_hero")
    return null
endfunction

function T_getItem takes timer t returns item
    return GetStoredInteger(objects(),I2S(H2I(t)),"m_item")
    return null
endfunction

function T_getItem2 takes timer t returns item
    return GetStoredInteger(objects(),I2S(H2I(t)),"m_item2")
    return null
endfunction

function reAdd_child takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local unit hero=T_getHero(t)
    local item bag=T_getItem(t)
    call UnitAddItem(hero,bag)
    call FlushStoredMission(objects(),I2S(H2I(t)))
    call DestroyTimer(t)
    set t=null
    set hero=null
    set bag=null
endfunction

function reAddItem takes unit hero,item it returns nothing
    local timer t=CreateTimer()
    local gamecache gc=objects()
    call StoreInteger(objects(),I2S(H2I(t)),"m_hero",H2I(hero))
    call StoreInteger(objects(),I2S(H2I(t)),"m_item",H2I(it))
    call TimerStart(t,0,false,function reAdd_child)
    set t=null
    set gc=null
endfunction

function Tro_Child takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local unit hero=T_getHero(t)
    call IssueImmediateOrder(hero,"replenishon")
    call IssueImmediateOrder(hero,"replenishlifeoff")
    call DestroyObject(I2S(H2I(t)))
    call DestroyTimer(t)
    set t=null
    set hero=null
endfunction

function TRO takes unit hero returns nothing
    local timer t=CreateTimer()
    call StoreInteger(objects(),I2S(H2I(t)),"m_hero",H2I(hero))
    call TimerStart(t,0,false,function Tro_Child)
endfunction


function GetItemCostById_Hero takes nothing returns unit
    return GetStoredInteger(objects(),"rccs","m_hero")
    return null
endfunction

function GetItemCostById_Shop takes nothing returns unit
    return GetStoredInteger(objects(),"rccs","m_shop")
    return null
endfunction


function GetItemCostById takes integer id,boolean whichtype,integer charges returns integer
    local unit h
    local unit s
    local player p
    local gamecache gc=objects()
    local string t=I2S(id)
    local integer gold=GetStoredInteger(gc,t,"m_gold")
    local integer lumber=GetStoredInteger(gc,t,"m_lumber")
    local integer def=GetStoredInteger(gc,t,"m_def")
    local item it=null
    if(not (gold==0 and lumber==0))then
        set gc=null
        if(def==0 or charges==0)then
            set charges=1
            set def=charges
        endif
        return charges/def*( B2I(whichtype)*gold+B2I(not whichtype)*lumber)
    endif
    set h=GetItemCostById_Hero()
    set s=GetItemCostById_Shop()
    set p=GetItemCostById_DummyPlayer()
    call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,50000)
    call SetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER,50000)
    call AddItemToStock(s,id,1,1)
    call IssueTargetOrder(s,"neutralinteract",h)
    call IssueNeutralImmediateOrderById(p,s,id)
    set it= UnitRemoveItemFromSlot(h,0)
    set def=GetItemCharges(it)
    call StoreInteger(gc,t,"m_def",def)
    call RemoveItemFromStock(s,id)
    call RemoveItem(it)
    set gold=50000-GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)
    set lumber=50000-GetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER)
    call StoreInteger(gc,t,"m_gold",gold)
    call StoreInteger(gc,t,"m_lumber",lumber)

    set h=null
    set s=null
    set gc=null
    set p=null
    set it=null
    if(def==0 or charges==0)then
        set charges=1
        set def=charges
    endif
    return charges/def*(B2I(whichtype)*gold+B2I(not whichtype)*lumber)
endfunction

function Bounty takes player whichplayer, integer bounty, real x, real y returns nothing
    local texttag t=CreateTextTag()
    local string s="+"
    local sound error=CreateSound( "Abilities\\\\Spells\\\\Items\\\\ResourceItems\\\\ReceiveGold.wav", false, true, true, 10, 10, "SpellsEAX" )
    if bounty<0 then
        set s=""
    endif
    call SetTextTagText(t,s+I2S(bounty),0.025)
    call SetTextTagPos(t,x,y, 0.00)
    call SetTextTagColor(t,255,220,0,255)
    call SetTextTagVelocity(t,0,0.03)
    if (GetLocalPlayer()==whichplayer) then
        call SetTextTagVisibility(t,true)
        call SetSoundPosition(error,x,y,0)
        call SetSoundVolume(error,127)        
        call StartSound( error )
        set s="UI\\\\Feedback\\\\GoldCredit\\\\GoldCredit.mdl"

    else
        call SetTextTagVisibility(t,false)
        set s=""
    endif
    call KillSoundWhenDone(error)
    call DestroyEffect(AddSpecialEffect(s,x,y))
    call SetTextTagFadepoint(t,2)
    call SetTextTagLifespan(t,3)
    call SetTextTagPermanent(t,false)
  set error=null
set t=null
endfunction


function InitTrig_RCCS_v_W takes nothing returns nothing
    local unit h=CreateUnit(GetItemCostById_DummyPlayer(),GetItemCostById_BuyerTypeId(),0,0,0)
    local unit s=CreateUnit(GetItemCostById_DummyPlayer(),GetItemCostById_ShopTypeId(),0,0,0)
    local gamecache gc=objects()
    local rect r=GetWorldBounds()
    call SetUnitX(h,GetRectMaxX(r)-10)
    call SetUnitX(s,GetRectMaxX(r))
    call SetUnitY(h,GetRectMaxY(r)-10)
    call SetUnitY(s,GetRectMaxY(r))
    call StoreInteger(gc,"rccs","m_hero",H2I(h))
    call StoreInteger(gc,"rccs","m_shop",H2I(s))
    call UnitAddAbility(s,'Asid')
    call UnitAddAbility(s,'Aneu')
    call UnitAddAbility(s,'Apit')
    call UnitAddAbility(s,'Avul')
    call UnitRemoveAbility(s,'Awan')
    call UnitAddAbility(s,'Aloc')
    call RemoveRect(r)
    set h=null
    set s=null
    set gc=null
    set r=null
endfunction

[/jass]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-5-22 13:22 , Processed in 0.040918 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表