RPG Un-Named ORPG

D.V.D

Make a wish
Reaction score
73
Working on the tauren area. I made a outpost. Here's a screenshot:

Untitled-132.jpg
 

wellwish3r

wishes wells.
Reaction score
52
im just wondering, can you actually go into the buildings? if so, there should probably and alternate camera view, that is only applied inside buildings

EDIT: oh and what about systems? there are some very good knockbacksystems, with sweet physics, so i would suggest that you compile a list of systems to be used, so we all use the same ones.

EDIT2: Im done with the spirit Guidance. The main trigger is a Combat Dispelled buff, so it can also be used for flasks, and other stuff that is supposed to be dispelled when taking damage. You can call that function via:
JASS:
call CDispellHot (unit target, real amount per tick, real duration,string effectstring,integer buff id)


Code:
JASS:
scope CDispellHoT

    struct SG
        unit targ
        real amount
        boolean end
        real dur
        string effectstring
        effect sfx
        real counter
        integer buffid
    endstruct

    globals
        private integer Total = 0
        private SG array D
        private timer T=CreateTimer()
    endglobals
    
    private function LoopActions takes nothing returns nothing
        local integer i = 0
        local location array loc2
        local texttag array txt
        local effect array sfx
        loop
            exitwhen i>=Total
            if D<i>.end then
                call DestroyEffect(D<i>.sfx)
                set D<i>.sfx = null
                call D<i>.destroy()
                set Total=Total-1
                if Total &gt; 0 then
                    set D<i>=D[Total]
                    set i=i-1
                else
                    call PauseTimer(T)
                endif
            else
                set txt<i> = CreateTextTag()
                set loc2<i> = GetUnitLoc(D<i>.targ)
                call SetUnitState(D<i>.targ,UNIT_STATE_LIFE,(GetUnitState(D<i>.targ,UNIT_STATE_LIFE)+D<i>.amount))
                call SetTextTagText(txt<i>,I2S(R2I(D<i>.amount)),TextTagSize2Height(8.00))
                call SetTextTagPos(txt<i>,GetLocationX(loc2<i>),GetLocationY(loc2<i>),150)
                call SetTextTagColor(txt<i>,51,255,0,255)
                call SetTextTagPermanent(txt<i>,false)
                call SetTextTagLifespan(txt<i>, .67)
                call SetTextTagFadepoint(txt<i>, 0.47)
                call SetTextTagVelocityBJ( txt<i>, 250.00, 90 )
                call RemoveLocation(loc2<i>)
                set loc2<i> = null
                set D<i>.counter = D<i>.counter + 1
                if D<i>.dur &lt;= D<i>.counter then
                    set D<i>.end = true
                endif
            endif
            set i = i+1
        endloop
    endfunction
    
    private function CancelHeal takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local integer i = 0
        local boolean found = false
        loop
            exitwhen found == true
            if u == D<i>.targ then
                set found = true
                set D<i>.end = true
                call UnitRemoveAbility(D<i>.targ,D<i>.buffid)
            endif
            set i = i+1
        endloop
        call TriggerClearActions(GetTriggeringTrigger())
        call DestroyTrigger(GetTriggeringTrigger())
    endfunction
    
    private function CancelGuidance takes unit u returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_DAMAGED)
        call TriggerAddAction(t,function CancelHeal)
    endfunction
    
    function CDispellHot takes unit t,real am, real d,string effstring, integer bid returns nothing
        local SG LSG = SG.create()
        set LSG.targ = t
        set LSG.amount = am
        set LSG.end = false
        set LSG.dur = d
        set LSG.counter = 0
        set LSG.effectstring = effstring
        set LSG.sfx = AddSpecialEffectTarget(LSG.effectstring,LSG.targ,&quot;origin&quot;)
        set LSG.buffid = bid
        call CancelGuidance(t)
        if Total == 0 then
            call TimerStart(T,1,true,function LoopActions)
        endif
        set D[Total] = LSG
        set Total = Total+1
    endfunction
    
endscope
</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>


I just made up a random duration/amount formula for testing.

EDIT3: Can you maybe send the the terrain? I want to see how the camera does with your terrain :p
 

Attachments

  • SpiritGuidance.w3x
    22.7 KB · Views: 223

Embrace_It

New Member
Reaction score
9
That outpost looks awesome :thup:

EDIT: oh and what about systems? there are some very good knockbacksystems, with sweet physics, so i would suggest that you compile a list of systems to be used, so we all use the same ones.

Agreed...

Btw, my own knockback system still needs to be able to kill trees and add an effect (like dust) to the unit according to terrain, so I wouldnt recommend it (my own system lol). Anyways, the SpellText library should be very useful however (will also be optimized further or modify if necessary). Both are included in the map.

I also made 'Taunt' since its not that hard to make :p
I will optimize the spell as soon as you decide what the best damage-formula is. I would suggest a positive factor on the stamina, to make it more prominent.

CODE:
JASS:

scope BattleCharge initializer Init
private keyword Data

//  -------------
// | START SETUP |
//  -------------
globals
    private integer Total = 0
    private Data array D
    private unit TempU
    private group TempG = CreateGroup()
    private timer t = CreateTimer()
    private filterfunc fltr
    
    // Constants
    private constant integer ABILITY_CODE       = &#039;A002&#039;
    private constant integer STAND_ANIM_INDEX   = 1 // Unit&#039;s &#039;stand&#039; animation index
    private constant integer RUNNING_ANIM_INDEX = 6 // Unit&#039;s &#039;run&#039; animation index
    private constant string DAMAGE_EFFECT = &quot;Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl&quot;
    private constant real IMPACT_AOE          = 150. // The area where units take damage
    private constant real INITIAL_SPEED       = 1. // The distance the unit moves every time
    private constant real ACCELERATION        = 2.5
    private constant real MAX_RANGE           = 800.
    private constant real SENSITIVITY         = 80. // Enemy units within this range stops the charge and deals damage
    private constant real FREQUENCY           = 0.04 // Frequency of the timer
    
    // Damage Constants
    private constant real STAMINA_FACTOR      = 1.
    private constant real DISTANCE_FACTOR     = 1.
endglobals

private function UnitFilter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(TempU)) and GetWidgetLife(GetFilterUnit()) &gt; 0.405 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)
endfunction

private function GetDamage takes unit source, integer level, real distance returns real
    return I2R(level) * (GetStaminaMelee(source) * STAMINA_FACTOR + distance * DISTANCE_FACTOR * 0.05)
endfunction
//  -----------
// | END SETUP |
//  -----------

private struct Data
    unit source
    real velocity = INITIAL_SPEED
    real d = 0.0
    real x
    real y
    real cos
    real sin
    boolean done = false
    
    static method create takes unit source, real angle returns Data
        local Data d = Data.allocate()
        
        set d.source = source
        call SetUnitPathing(source, false)
        set d.x = GetUnitX(source)
        set d.y = GetUnitY(source)
        set d.cos = Cos(angle)
        set d.sin = Sin(angle)
        
        return d
    endmethod
    
    method move takes nothing returns nothing
        local unit f
        set TempU = .source
        
        set .x = .x + .velocity * .cos
        set .y = .y + .velocity * .sin
        
        call GroupEnumUnitsInRange(TempG, .x, .y, SENSITIVITY, Filter(function UnitFilter))
        if (.d &lt;= MAX_RANGE and CheckPathability(.x, .y) and FirstOfGroup(TempG) == null) then
            //call SetUnitAnimation(.source, &quot;walk&quot;)
            call SetUnitAnimationByIndex(.source, RUNNING_ANIM_INDEX)
            call SetUnitX(.source, .x)
            call SetUnitY(.source, .y)
        else
             set .done = true
        endif
        
        call GroupClear(TempG)
        set .d = .d + .velocity
        set .velocity = .velocity + ACCELERATION
        
        set f = null
    endmethod
    
    method onDestroy takes nothing returns nothing
        local unit f
        local real angle
        local real damage = GetDamage(.source, GetUnitAbilityLevel(.source, ABILITY_CODE), .d)
        local real tx
        local real ty
        set TempU = .source
        
        call SetUnitAnimationByIndex(.source, STAND_ANIM_INDEX)
        call GroupEnumUnitsInRange(TempG, .x, .y, IMPACT_AOE, Filter(function UnitFilter))
        
        loop
            set f = FirstOfGroup(TempG)
            exitwhen f == null
            set tx = GetUnitX(f)
            set ty = GetUnitY(f)
            set angle = Atan2(ty - GetUnitY(.source), tx - GetUnitX(.source))
            call UnitDamageTarget(.source, f, damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
            call CreateFloatingDamagePos(damage, tx, ty, &quot;|cffff0000&quot;)
            call DoKnockBack(.source, f, 60.0, 6.0, angle, 0.0, false, false)
            call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, f, &quot;chest&quot;))
            call GroupRemoveUnit(TempG, f)
        endloop
        
        call GroupClear(TempG)
        call SetUnitPathing(.source, true)
        
        set .source = null
        set f = null
    endmethod
endstruct

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == ABILITY_CODE
endfunction

private function Loop takes nothing returns nothing
    local integer i = Total - 1
    
    loop
        exitwhen i &lt; 0
        if D<i>.done == true then
            call D<i>.destroy()
            set D<i> = D[Total - 1]
            set Total = Total - 1
        else
            call D<i>.move()
        endif
        set i = i - 1
    endloop
    
    if Total == 0 then
        call PauseTimer(t)
    endif
endfunction

private function Actions takes nothing returns nothing
    local unit source = GetTriggerUnit()
    local location sloc = GetSpellTargetLoc()
    local real angle = Atan2(GetLocationY(sloc) - GetUnitY(source), GetLocationX(sloc) - GetUnitX(source))
    local Data d = Data.create(source, angle)
    call d.move()
    
    if Total == 0 then
        call TimerStart(t, FREQUENCY, true, function Loop)
    endif
    
    set D[Total] = d
    set Total = Total + 1
    
    call RemoveLocation(sloc)
    set source = null
endfunction

// Main function
private function Init takes nothing returns nothing
    local trigger trig = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(trig, Condition(function Conditions))
    call TriggerAddAction(trig, function Actions)
    
    set fltr = Filter(function UnitFilter)
    
    set trig = null
endfunction

endscope
</i></i></i></i>


However, I really suck at animations, and I cant get the "walk" animation to work. I did this spell before and was lucky to find the right index for the walk animation, but that was with another unit.

Also, will the hero's have the standard set of abilities (3 normal, 1 ulti?) or spellbooks?

I will begin coding 'Battle Rage' meanwhile :)
 

Attachments

  • Combat System v3 (with Warrior).w3x
    43.4 KB · Views: 222

wellwish3r

wishes wells.
Reaction score
52
Well for the dust animation, just add an ImpaleDust special effect at the loc whenever you move the unit^^
 

D.V.D

Make a wish
Reaction score
73
Testing abilities now. I wanted to use the knock back but instead of destroying tree's, since the tree's will be like 5 times bigger than you, we should make the tree's stop you and stun you so instead of destroying them, they stop you. The camera inside buildings still needs to be tested, we don't know how it looks inside buildings.
 

Embrace_It

New Member
Reaction score
9
Well for the dust animation, just add an ImpaleDust special effect at the loc whenever you move the unit^^

Its more of a "lazy" problem though :p I actually imported all necessary effects, and I will gladly finish it, if it will be of any use.
 

D.V.D

Make a wish
Reaction score
73
Battle Charge: The spell is good but the unit isn't playing any animation. Make him play a attack aniimation and if possible, specificly attack 2 animation. The units hit should play death animation. When he hits the target area, create a dummy that is a war stomp set to -90 degrees and make that dummy appear in front of every hit unit. Spell is smooth and is well made just addinng effects makes it more cooler and gives a better feeling about the game.

Spirit Guidance: Works good, just instead of canceling the heal, maybe reduce the heal by 3 quarters? So he doesn't have to step out of battle, heal and go back into battle.

The inventory system for atleast this version won't be using DGUI or any other system for interface. The inventory system will be the same as the one in Diablo 3 wc3 beta 1.17. Only dfferences, different items will be set, and you will have a seprate inventory for holding items and, you could click to change the items that are equiped. In total, you will hold 12 items with stacking included.
 

wellwish3r

wishes wells.
Reaction score
52
Done:

JASS:
scope CDispellHoT

    struct SG
        unit targ
        real amount
        boolean end
        real dur
        string effectstring
        effect sfx
        real counter
        integer buffid
    endstruct

    globals
        private integer Total = 0
        private SG array D
        private timer T=CreateTimer()
    endglobals
    
    private function LoopActions takes nothing returns nothing
        local integer i = 0
        local location array loc2
        local texttag array txt
        local effect array sfx
        loop
            exitwhen i&gt;=Total
            if D<i>.end then
                call DestroyEffect(D<i>.sfx)
                set D<i>.sfx = null
                call D<i>.destroy()
                set Total=Total-1
                if Total &gt; 0 then
                    set D<i>=D[Total]
                    set i=i-1
                else
                    call PauseTimer(T)
                endif
            else
                set txt<i> = CreateTextTag()
                set loc2<i> = GetUnitLoc(D<i>.targ)
                call SetUnitState(D<i>.targ,UNIT_STATE_LIFE,(GetUnitState(D<i>.targ,UNIT_STATE_LIFE)+D<i>.amount))
                call SetTextTagText(txt<i>,I2S(R2I(D<i>.amount)),TextTagSize2Height(8.00))
                call SetTextTagPos(txt<i>,GetLocationX(loc2<i>),GetLocationY(loc2<i>),150)
                call SetTextTagColor(txt<i>,51,255,0,255)
                call SetTextTagPermanent(txt<i>,false)
                call SetTextTagLifespan(txt<i>, .67)
                call SetTextTagFadepoint(txt<i>, 0.47)
                call SetTextTagVelocityBJ( txt<i>, 250.00, 90 )
                call RemoveLocation(loc2<i>)
                set loc2<i> = null
                set D<i>.counter = D<i>.counter + 1
                if D<i>.dur &lt;= D<i>.counter or GetUnitAbilityLevel(D<i>.targ,D<i>.buffid) &lt; 1 then
                    set D<i>.end = true
                endif
            endif
            set i = i+1
        endloop
    endfunction
    
    private function CancelHeal takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local integer i = 0
        local boolean found = false
        loop
            exitwhen found == true
            if u == D<i>.targ then
                set found = true
                set D<i>.amount = (D<i>.amount)*0.25
            endif
            set i = i+1
        endloop
        call TriggerClearActions(GetTriggeringTrigger())
        call DestroyTrigger(GetTriggeringTrigger())
    endfunction
    
    private function CancelGuidance takes unit u returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_DAMAGED)
        call TriggerAddAction(t,function CancelHeal)
    endfunction
    
    function SpiritGuidance takes unit t,real am, real d,string effstring, integer bid returns nothing
        local SG LSG = SG.create()
        set LSG.targ = t
        set LSG.amount = am
        set LSG.end = false
        set LSG.dur = d
        set LSG.counter = 0
        set LSG.effectstring = effstring
        set LSG.sfx = AddSpecialEffectTarget(LSG.effectstring,LSG.targ,&quot;origin&quot;)
        set LSG.buffid = bid
        call CancelGuidance(t)
        if Total == 0 then
            call TimerStart(T,1,true,function LoopActions)
        endif
        set D[Total] = LSG
        set Total = Total+1
    endfunction
    
endscope
</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
 

Attachments

  • SpiritGuidance v2.w3x
    22.2 KB · Views: 215

D.V.D

Make a wish
Reaction score
73
Works perfectly. Really nice. The tauren area is shaping out nicely too.
 

D.V.D

Make a wish
Reaction score
73
The mountian reigon in the world map shown on the first post. Its the dark brown area. The desert is 100% done in terrain but isn't playable. Here's a rouge skill:

Critical Strike:
Passive
The rouge has a chance to deal extra damage equal to the units agility. The rouge's attack bleeds the unit dealing damage per second to the unit for 7 seconds.
Note: Make the damage increase per level and not based on attributes.
 

Embrace_It

New Member
Reaction score
9
Wow, just remembered...I should probably mention that 'NordCoder' is my other name in case your wondering how he is (see library docs) :rolleyes:

ill take the dips on that one :p

Curses! Foiled again!
 

Embrace_It

New Member
Reaction score
9
Here is the new version of Battle Charge (just overwrite the previous map)

Changes:
Code:
- The Tauren Warrior now properly displays animation
- The Tauren Warrior initiates 'attack 2' animation before hitting the units for
   better timing and effect.
- The War Stomp effect appears on units that are hit.

I was not sure about two things though:

1. How should I set the dummy unit to -90 degrees (or something similar?)
2. Playing the 'death' animation for units that are hit will make them "die" and then they will just lie there, until you attack them. It doesnt really work, unless I misunderstood you.

I will await your feedback! ;)
 

Attachments

  • Combat System v3 (with Warrior).w3x
    43.7 KB · Views: 219

wellwish3r

wishes wells.
Reaction score
52
Just checked it out. There are two things about the animations that are rather weird. One being that he only glides over the ground, not walks.

The other is that the attack animation plays to late. How about making him play the animation when a target unit, or the max range comes within 200 of the tauren, so the knock back and hit match? Just a suggestion :p
 
General chit-chat
Help Users

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top