- Joined
- Aug 3, 2008
- Messages
- 2,345
Anyone have any ideas for a really hard-to-make vJass system? I need a good challenge. BTW I won't do anything that requires imports (such as full screen inventory, etc)
You can do a farming system like in Age of Empires 2
including food sources like berries, hunting and ofc farming on a field
Where hunters automatically start hunting a new deer/boar when there is no flesh left on the old one and where you have to rebuild the fields when they are harvested
So basically you want me to remake every single spell in wc3 to use different damage formulas. No.
None of the spells are difficult to make. I want a challenge.You don't have to make every spell, just choose the one that will be most difficult to make, I am assuming that you will use vJASS. Try Immolation with min-max damage.
3) I detect when a unit is issued an order targeting a widget. If this order is "repair", then I check to see if the target unit has my data attached to it. If so, I store the triggering unit in the attached group.
Only humans can have more than one builder working on the same building at the same time, however, so I don't see why this is a problem.Sorry, does not work. Only human builders do this and only if the unit can issue the repair order. Undead, orc and NE do not build like this so there is no repair order issued.
Can already be done in Warcraft 3 normally by using waypoint commands. (Hold shift and give orders)Another one i would like, based off this Age of Empires idea, is this: When a unit in Age of Empires is issued an order to build some wall for example, you can extend the order and make a path of dummy walls, which orders that unit once it finishes construction of the first wall, to go to the second, until all of them are done. In Warcraft 3, you can order a unit to build a building. Then, at the Point of issued order, you get that building with 50% transparency, until the ordered unit reaches it and starts constructing it. How would you do the same thing but for multiple buildings, which are defined through a drag-out of the mouse?
o <- Building to be constructed (Warcraft 3)
oooooooooooooo <- Buildings to be constructed (Age of Empires)
That's extremely basic.or conversation spell from AoE 1&2 from monks and priests
If more priest convert, it take less time (but not like if 2, it will take 50%, it has its own formula)
More of a creativity problem than a coding problem once you figure out the solution--something I wrote a while ago and was surprised at how easy it was and yet how it was weird as you didn't tend to notice it right away:
Figure out a specific event spread system (damage detect, acquire target detect, whatever) which will not leak in any way and at the same time will not have lag issues with ridiculous numbers of units (thousands). You may assume the user is competent.
This is an excersize rather than a request, if you feel like trying something different.
Anyone have any ideas for a really hard-to-make vJass system? I need a good challenge. BTW I won't do anything that requires imports (such as full screen inventory, etc)
@Poot
I'm currently working on DSG's suggestion, but I have an idea of how you might do that:
1) When an event is registered using your special register function, add this event to a hashtable and register every unit on the map to a new trigger.
2) Detect units entering the map and add them to every trigger with every event.
3) Periodically destroy all triggers and re-register units. (?)
4) When one of your triggers in the array is fired, loop through the array of triggers registered to the system and fire each of them.
Done.
@Dreadnought
A whole game... hmm... I don't think so.
Anyway, STOP now. I've had enough input. Thank you.
/******************************************************************************************
* GetBuildingUnit(s)
* by Element of Water (EoW)
*******************************************************************************************
* Introduction
*
* GetBuildingUnit(s) is a system designed to retrieve the constructing unit (or units) in
* response to a CONSTRUCT_START, CONSTRUCT_CANCEL or CONSTRUCT_FINISH event. You may also
* use it on a building to retrieve its constructor(s) at any time during its construction.
* It requires:
*
* - JassHelper by Vexorian
* - TimerUtils by Vexorian
* - GroupUtils by Rising_Dusk
* - BoolexprUtils by Vexorian
* - Table by Vexorian
* - InRangeWithSource by Element of Water (
********************************************************************************************
* Functions
*
* There are two functions in the library available for use outside of it. These are:
*
* 1) function GetConstructingUnit takes unit building returns unit
* 2) function GetConstructingUnits takes unit building returns group
*
* 1) Should be used when you know that only unit can be constructing the building, IE in
* response to a CONSTRUCT_START event or when you know the race of the building player
* is not one which allows more than one worker to work on one building at once.
*
* 2) Should be used if it is possible that more than one unit may be working on the
* building, as (1) will simply return a random unit in the group which will be returned
* by this function
*******************************************************************************************/
library GetBuildingUnits initializer Init requires TimerUtils, GroupUtils, BoolexprUtils, Table
private function TriggerRegisterAnyUnitEvent takes trigger trig, playerunitevent whichEvent returns nothing
local integer i = 0
loop
exitwhen i >= bj_MAX_PLAYERS
call TriggerRegisterPlayerUnitEvent(trig, Player(i), whichEvent, BOOLEXPR_TRUE)
set i = i + 1
endloop
endfunction
//============================================
globals
private constant integer REPAIR_ID = 852024
private constant integer SMART_ID = 851971
private constant integer HUMAN_REPAIR_ABIL_ID = 'Ahrp'
private constant real CLEAR_DATA_TIMER = 2.0
//============================================
private HandleTable ht
private HandleTable ht2
private unit TempUnit = null
endglobals
//============================================
globals
private real X
private real Y
private unit U
private unit B
private real D
private group ENUM_GROUP = CreateGroup()
private boolexpr TheFilter
endglobals
private function FilterFunc takes nothing returns boolean
local real dx
local real dy
local real dist
local unit u = GetFilterUnit()
if not IsUnitType(u, UNIT_TYPE_STRUCTURE) and ht2.exists(u) then
if ht2[u] == GetUnitTypeId(B) then
set dx = GetUnitX(GetFilterUnit()) - X
set dy = GetUnitY(GetFilterUnit()) - Y
set dist = SquareRoot(dx*dx + dy*dy)
if dist < D then
set D = dist
set U = GetFilterUnit()
endif
endif
endif
set u = null
return false
endfunction
private function ClosestUnit takes real x, real y, unit u, player owner returns unit
set X = x
set Y = y
set U = null
set B = u
set D = 1000000
call GroupEnumUnitsOfPlayer(ENUM_GROUP, owner, TheFilter)
return U
endfunction
//============================================
private struct Data
unit u
group g
static method create takes nothing returns Data
local Data d = Data.allocate()
set d.g = NewGroup()
return d
endmethod
method onDestroy takes nothing returns nothing
call ReleaseGroup(.g)
endmethod
endstruct
//============================================
function GetConstructingUnit takes unit building returns unit
local Data d = ht[building]
if not ht.exists(building) then
call BJDebugMsg("NO!")
endif
return FirstOfGroup(d.g)
endfunction
function GetConstructingUnits takes unit building returns group
local Data d
if ht.exists(building) then
set d = ht[building]
return d.g
endif
return null
endfunction
//============================================
private function ClearData takes nothing returns nothing
local timer t = GetExpiredTimer()
local Data d = GetTimerData(t)
call d.destroy()
call ReleaseTimer(t)
set t = null
endfunction
private function StopBuilding takes nothing returns boolean
local Data d
local timer t
if ht.exists(GetTriggerUnit()) then
set d = ht[GetTriggerUnit()]
set t = NewTimer()
call SetTimerData(t, d)
call TimerStart(t, CLEAR_DATA_TIMER, false, function ClearData)
set t = null
endif
return false
endfunction
private function StartBuilding takes nothing returns boolean
local Data d
local unit u = GetTriggerUnit()
local unit c = ClosestUnit(GetUnitX(u), GetUnitY(u), u, GetOwningPlayer(u))
if c != null then
set d = Data.create()
call GroupAddUnit(d.g, c)
set d.u = GetTriggerUnit()
set ht[GetTriggerUnit()] = d
set ht[c] = d
endif
set u = null
set c = null
return false
endfunction
private function AnyOrder takes nothing returns boolean
local integer order = GetIssuedOrderId()
local Data d
local unit u
if order == REPAIR_ID then
//an additional builder has been ordered to work on the building
if ht.exists(GetOrderTarget()) then
set d = ht[GetOrderTarget()]
call GroupAddUnit(d.g, GetTriggerUnit())
set ht[GetTriggerUnit()] = d
endif
elseif order == SMART_ID then
endif
if ht2.exists(GetTriggerUnit()) then
if ht2[GetTriggerUnit()] != order then
set ht2[GetTriggerUnit()] = 0
endif
endif
return false
endfunction
private function PointOrder takes nothing returns boolean
local integer id = GetIssuedOrderId()
local real x = GetOrderPointX()
local real y = GetOrderPointY()
local unit u = CreateUnit(Player(13), id, x, y, 90.)
if u != null then
if IsUnitType(u, UNIT_TYPE_STRUCTURE) then
set ht2[GetTriggerUnit()] = id
endif
call RemoveUnit(u)
endif
return false
endfunction
//============================================
private function Init takes nothing returns nothing
//Create the trigger to detect point orders.
local trigger t = CreateTrigger()
local boolexpr c = Condition(function PointOrder)
call TriggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerAddCondition(t, c)
//============================================
//Create the trigger to detect any order.
set t = CreateTrigger()
set c = Condition(function AnyOrder)
call TriggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t, c)
//============================================
//Create the trigger to detect start building.
set t = CreateTrigger()
set c = Condition(function StartBuilding)
call TriggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_CONSTRUCT_START)
call TriggerAddCondition(t, c)
//============================================
//Create the trigger to detect stop building.
set t = CreateTrigger()
set c = Condition(function StartBuilding)
call TriggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH)
call TriggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL)
call TriggerAddCondition(t, c)
//============================================
//Initialise some stuff
set ht = HandleTable.create()
set ht2 = HandleTable.create()
set TheFilter = Filter(function FilterFunc)
//Clean leaks
set t = null
set c = null
endfunction
endlibrary
Meh, I always forget about cheats. I don't like cheating in games (campaign, single player melee), so I just forget about them when they're useful.Well because only 1 unit ever starts to build a building and can build a building for most races. Only human buildings support 2 units or more building at once, but still there will always be only one initial builder who actually started the building which my sytem resturns. My system runs when a unit starts building a building and gives you the building and the builder (not when a unit joins or helps build a building). It was designed so that you can get stats from the orignal builder, eg in the map I made each builder can only have a limated number of buildings at a time unique to that builder.
As for the gold thing.... It was alpha so easy testing was not added. Also is it really so hard to "greedisgood 1000000"? Afterall that is how I test it. I put the hero on hold till 1.24 is out as I believe the hashtables are far faster than my hash system.
Good old WC3 legal cheatcodes, thereisnospoon, whosyourdaddy 9999999 (yes it takes an integer which does nothing lol), greedisgood 9999999, warpten. Do not know how spell testers could live with out them.
Ofcourse there is the no CD one as well as the no food one, but you do hardly ever need them.