- Joined
- Jul 10, 2007
- Messages
- 6,306
So I've been working on a spiffy new system. Just sharing the previews here to see if there are any features people want or if there are any things in this that people think are a bad idea.
Each unit has a squad under them. Whenever that unit is issued an order, the squad under them is issued an order. In this way, if you have a unit with 12 units under them each with 12 units under them and you order the top unit, you will order 157 units.
commander- 1
12 units under commander- 12
12 units per sub unit- 144
144+12+1 = 157
Chart:
Unit- (unit1(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit2(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit3(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit4(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit5(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit6(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit7(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit8(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit9(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit10(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit11(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit12(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12))
Obviously, you probably only want squads to be bodyguards or actual squads. You don't want your entire army under your commanders, lol, but with a commanding system, you could order squads under your commanders ;P.
Each unit has a leash, meaning that units under them can't go farther than the leash. With a command system, you could set leashes for specific squads (a unit in charge of a battalion of 12 squads may have a leash for those 12 squads, a unit in charge of a set of an army of 12 battalions may have an epic leash or no leash at all).
So yea...
I also introduced until roles (just 4).
LEADER_MELEE
LEADER_RANGE
MELEE
RANGE
Obviously this can be set up to be squad roles too if you were to have squads of squads with the ordering.
Each position has a priority value on the role.
Each unit has strengths for different roles (only MELEE and RANGE strengths). A unit is placed into the highest priority position they can go into given their strength (loop through all units in squad in order from highest priority to lowest and compare strengths).
And that's sorta what I have atm.
This entire thing only runs on two hashtables right now ;D.
This is the code I have so far (priorities aren't ordered atm and the list of positions should be split up into 2 lists, one for each role as well as 2 vars, the squad leader positions for melee and ranged)
Yea, this still has quite a lot of work, but I felt like sharing ;D.
After this is done, I'll make the commanding lib >: p. Then I'll make a carrier lib for units to carry commands to other units ;D.
Welcome to the beginning of epic RTS.
For those of you who've been keeping up with my work, I know I was working on Bounty, but I'm waiting for Bribe to submit the Damage stuff I helped him with since Bounty requires damage detection for accuracy ;|.
And no, I haven't set up the actual formations yet. I got the positions down and what not, but the formations will be a lot of work. If a formation isn't present, it'll just be a group order. In order to maintain formations, all unit speeds will be set to the slowest unit in the group. If the slowest unit is removed, they'll be set to the next slowest ;P, etc. For squads of squads, this can get fun to code... ; D
Event is in there for dispersing squads (when the commander dies, chaos ensues).
This snippet should make RTS games more RTS like : P, fuahaha. It also makes it easier to micro manage as you don't have to handle each individual unit, but can rather order various squads about or w/e. You could use this for a variety of purposes: enhancing melee games, making new hardcore RTS games, or w/e else.
Yea, still has a lot of work, but ehhh... I've been wanting to code this for a long time ;O.
Each unit has a squad under them. Whenever that unit is issued an order, the squad under them is issued an order. In this way, if you have a unit with 12 units under them each with 12 units under them and you order the top unit, you will order 157 units.
commander- 1
12 units under commander- 12
12 units per sub unit- 144
144+12+1 = 157
Chart:
Unit- (unit1(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit2(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit3(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit4(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit5(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit6(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit7(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit8(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit9(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit10(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit11(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12), unit12(unit1, unit2, unit3, unit4, unit5, unit6, unit7, unit8, unit9, unit10, unit11, unit12))
Obviously, you probably only want squads to be bodyguards or actual squads. You don't want your entire army under your commanders, lol, but with a commanding system, you could order squads under your commanders ;P.
Each unit has a leash, meaning that units under them can't go farther than the leash. With a command system, you could set leashes for specific squads (a unit in charge of a battalion of 12 squads may have a leash for those 12 squads, a unit in charge of a set of an army of 12 battalions may have an epic leash or no leash at all).
So yea...
I also introduced until roles (just 4).
LEADER_MELEE
LEADER_RANGE
MELEE
RANGE
Obviously this can be set up to be squad roles too if you were to have squads of squads with the ordering.
Each position has a priority value on the role.
Each unit has strengths for different roles (only MELEE and RANGE strengths). A unit is placed into the highest priority position they can go into given their strength (loop through all units in squad in order from highest priority to lowest and compare strengths).
And that's sorta what I have atm.
This entire thing only runs on two hashtables right now ;D.
This is the code I have so far (priorities aren't ordered atm and the list of positions should be split up into 2 lists, one for each role as well as 2 vars, the squad leader positions for melee and ranged)
Yea, this still has quite a lot of work, but I felt like sharing ;D.
After this is done, I'll make the commanding lib >: p. Then I'll make a carrier lib for units to carry commands to other units ;D.
Welcome to the beginning of epic RTS.
For those of you who've been keeping up with my work, I know I was working on Bounty, but I'm waiting for Bribe to submit the Damage stuff I helped him with since Bounty requires damage detection for accuracy ;|.
And no, I haven't set up the actual formations yet. I got the positions down and what not, but the formations will be a lot of work. If a formation isn't present, it'll just be a group order. In order to maintain formations, all unit speeds will be set to the slowest unit in the group. If the slowest unit is removed, they'll be set to the next slowest ;P, etc. For squads of squads, this can get fun to code... ; D
Event is in there for dispersing squads (when the commander dies, chaos ensues).
This snippet should make RTS games more RTS like : P, fuahaha. It also makes it easier to micro manage as you don't have to handle each individual unit, but can rather order various squads about or w/e. You could use this for a variety of purposes: enhancing melee games, making new hardcore RTS games, or w/e else.
Yea, still has a lot of work, but ehhh... I've been wanting to code this for a long time ;O.
JASS:
library Formation uses /*
*/UnitIndexer /*hiveworkshop.com/forums/jass-functions-413/unit-indexer-172090/
*/Event /*hiveworkshop.com/forums/submissions-414/snippet-event-186555/
*/UnitEvent //
globals
private hashtable table = InitHashtable()
private hashtable positioning = InitHashtable()
endglobals
private module UnitSquadMod
private group orderGroup
private thistype leader
private UnitFormationPosition position
readonly integer count
real leash
UnitFormation formation
private static method targetOrder takes nothing returns boolean
call GroupTargetOrderById(thistype(GetUnitUserData(GetTriggerUnit())).orderGroup, GetIssuedOrderId(), GetOrderTarget())
return false
endmethod
private static method pointOrder takes nothing returns boolean
call GroupPointOrderById(thistype(GetUnitUserData(GetTriggerUnit())).orderGroup, GetIssuedOrderId(), GetOrderPointX(), GetOrderPointY())
return false
endmethod
private static method unitOrder takes nothing returns boolean
call GroupImmediateOrderById(thistype(GetUnitUserData(GetTriggerUnit())).orderGroup, GetIssuedOrderId())
return false
endmethod
private static method index takes nothing returns boolean
set thistype(GetIndexedUnitId()).orderGroup = CreateGroup()
return false
endmethod
private static method deindex takes nothing returns boolean
call GroupClear(thistype(GetIndexedUnitId()).orderGroup)
call DestroyGroup(thistype(GetIndexedUnitId()).orderGroup)
set thistype(GetIndexedUnitId()).orderGroup = null
return false
endmethod
method add takes unit u returns nothing
local UnitRole role = GetUnitTypeId(u)
local UnitRole role2 = 0
local thistype uid = GetUnitUserData(u)
local thistype uid2 = 0
local integer primary = role.primary
local integer posRole = 0
local UnitRole secondary = role.secondary
local integer strength = role[primary].strength
local integer strength2 = 0
local integer i = formation.positions
local UnitFormationPosition pos
//always add the unit in if there is no formation present
//if there is a formation present, only add if there is room
set uid.leader = this
call GroupAddUnit(orderGroup, u)
//loop will auto exit with no formation present
loop
exitwhen i == 0 or uid == 0
set pos = formation[i]
set uid2 = this[pos]
set role2 = GetUnitTypeId(u)
set posRole = pos.role
set strength2 = role2[posRole].strength
if (primary == posRole and strength > strength2) then
endif
set i = i - 1
endloop
set i = formation.positions
set
loop
exitwhen i == 0 or uid == 0
set i = i - 1
endloop
endmethod
static method remove takes unit u returns nothing
local thistype this = thistype(GetUnitUserData(u)).leader
call GroupRemoveUnit(leader.orderGroup, u)
set leader = 0
endmethod
private static method onInit takes nothing returns nothing
local integer i = 16
local trigger t = CreateTrigger()
local trigger t2 = CreateTrigger()
local trigger t3 = CreateTrigger()
call UnitIndexer.INDEX.register(Condition(function thistype.index))
call UnitIndexer.DEINDEX.register(Condition(function thistype.deindex))
call TriggerAddCondition(t, Condition(function thistype.pointOrder))
call TriggerAddCondition(t2, Condition(function thistype.targetOrder))
call TriggerAddCondition(t3, Condition(function thistype.unitOrder))
loop
set i = i - 1
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
call TriggerRegisterPlayerUnitEvent(t2, Player(i), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
call TriggerRegisterPlayerUnitEvent(t3, Player(i), EVENT_PLAYER_UNIT_ISSUED_UNIT_ORDER, null)
exitwhen i == 0
endloop
set t = null
set t2 = null
set t3 = null
endmethod
endmodule
private keyword allocate
private keyword deallocate
private keyword POSITION
private keyword positionset
private module UnitFormationPositionMod
static constant integer DIRECTION = 0
static constant integer FACING = 1
static constant integer DISTANCE = 2
static constant integer ROLE = 3
private static constant integer RECYCLER = 4
static constant integer ROLE_PRIORITY = 5
static constant integer POSITION = 6
static constant integer OPEN = 7
private static integer count = 0
private static integer recycleCount = 0
static method allocate takes real direction, real facing, real distance, UnitRole role, integer rolePriority, integer position returns thistype
local thistype this
if (recycleCount == 0) then
set count = count + 1
set this = count
else
set recycleCount = recycleCount - 1
set this = LoadInteger(table, recycleCount, RECYCLER)
endif
set this[DIRECTION] = direction
set this[FACING] = facing
set this[DISTANCE] = distance
set priority = rolePriority
set positionset = position
set this.role = role
return this
endmethod
method deallocate takes nothing returns nothing
call SaveInteger(table, recycleCount, RECYCLER, this)
set recycleCount = recycleCount + 1
endmethod
endmodule
private module UnitFormationMod
private static integer count = 0
readonly integer positions
static method create takes nothing returns thistype
set count = count + 1
return count
endmethod
method addPosition takes real direction, real facing, real distance, UnitRole role, integer rolePriority returns UnitFormationPosition
local UnitFormationPosition new = UnitFormationPosition.allocate(direction, facing, distance, role, rolePriority, positions)
set positions = positions + 1
set this[positions] = new
return new
endmethod
method removePosition takes UnitFormationPosition pos returns nothing
local integer p = pos.position
local UnitFormationPosition indexed = this[positions]
set this = indexed
set indexed.positionset = p
set positions = positions - 1
endmethod
endmodule
private module UnitRoleMod
readonly static thistype MELEE = 0
readonly static thistype RANGED = 1
static constant integer MAX_STRENGTH = -1
static constant integer NO_STRENGTH = 0
method operator [] takes integer role returns integer
return LoadInteger(table, -this, -role)
endmethod
method operator []= takes integer role, integer strength returns nothing
call SaveInteger(table, -this, -role, strength)
endmethod
method operator role takes nothing returns integer
local integer primary = this[MELEE]
local integer secondary = this[RANGED]
if (primary > secondary) then
return MELEE
endif
return RANGED
endmethod
method operator secondary takes nothing returns integer
local integer primary = this[MELEE]
local integer secondary = this[RANGED]
if (primary <= secondary) then
return MELEE
endif
return RANGED
endmethod
endmodule
struct UnitRole extends array
implement UnitRoleMod
endstruct
struct UnitFormationPosition extends array
method operator role takes nothing returns integer
return LoadInteger(table, this, ROLE)
endmethod
private method operator role= takes UnitRole role returns nothing
call SaveInteger(table, this, ROLE, role)
endmethod
method operator [] takes integer property returns real
return LoadReal(table, this, property)
endmethod
private method operator []= takes integer property, real val returns nothing
call SaveReal(table, this, property, val)
endmethod
method operator position takes nothing returns integer
return LoadInteger(table, this, POSITION)
endmethod
method operator positionset= takes integer p returns nothing
call SaveInteger(table, this, POSITION, p)
endmethod
method operator priority takes nothing returns integer
return LoadInteger(table, this, ROLE_PRIORITY)
endmethod
method operator priority= takes integer newPriority returns nothing
call SaveInteger(table, this, ROLE_PRIORITY, newPriority)
endmethod
implement UnitFormationPositionMod
endstruct
struct UnitFormation extends array
method operator [] takes integer index returns UnitFormationPosition
return LoadInteger(table, -this, index)
endmethod
private method operator []= takes integer index, UnitFormationPosition pos returns nothing
call SaveInteger(table, -this, index, pos)
endmethod
implement UnitFormationMod
endstruct
struct UnitSquad extends array
static method operator [] takes unit u returns thistype
return GetUnitUserData(u)
endmethod
method operator [] takes UnitFormationPosition position returns integer
return LoadInteger(positioning, this, position)
endmethod
private method operator []= takes UnitFormationPosition position, integer untiId returns nothing
call SaveInteger(positioning, this, position, unitId)
endmethod
implement UnitSquadMod
endstruct
endlibrary