Serenity09 Moderator
| Subject: Resources that I can't imagine any1 will ever use Wed Feb 15, 2012 5:57 pm | |
| Wow everytime I use that color I always think it will look awesome and then its just completely blinding. holy damn. well you all can suffer. here are a few things that I made for my dream world map that I never got around to finishing. a lot of it is really cool almost all of these require Jass New Gen Editor to save properly (an easy way to tell is if you see any of the words "scope" "library" "struct" then you definitely need it) Platform Escape Style Movement: - Spoiler:
You need to import a few things to use this Below are 3 sections of code. In the editor make 3 different triggers and convert them to custom text (by clicking on the trigger and going to edit -> convert to custom text) the name of each trigger doesnt matter, but the more relevant the better (for sanity sake) - Code:
-
library KeyAction initializer OnInit //============================================================================== // KeyAction v0.1.0 //============================================================================== // Credits: //------------------------------------------------------------------------------ // Written By: // Earth-Fury //------------------------------------------------------------------------------ // I don't care if you credit me or not if you use this. However, you must not // misrepresent the source of this library in any way. This includes, but is not // limited to claiming yourself to be the sole contributor to a map which uses // this library. // //============================================================================== // Introduction: //------------------------------------------------------------------------------ // KeyAction is a library that provides a nicer, simpler API for dealing with // arrow key events. There is a speed penalty associated with using this // library as opposed to the native trigger events. However, this speed loss is // tiny, and only has an effect when a user actively presses or releases any of // the arrow keys. // // Note that arrow keys have a noticeable delay in single player, and rather // large delays in multiplayer. This is the fault of the game, not a fault in // this library. // // For the sake of simplicity and sanity, it is only possible to register events // for any arrow key click. If you are only interested in some combination of // keys and pressed/unpressed events, you have to filter out the undesired ones // in the callback. // //============================================================================== // API Guide //------------------------------------------------------------------------------ // This library uses integers to represent keys. The following constants are // defined by this library to make referring to keys simpler: // // KEY_DOWN = 0 // KEY_UP = 1 // KEY_LEFT = 2 // KEY_RIGHT = 3 // //------------------------------------------------------------------------------ // This library provides mechanisms for knowing if a key is currently pressed // or not, as well as knowing the general direction a pair of opposing keys is // representing. The API for both is simple function calls: // // function GetPlayerKeyState // takes player who, integer key // returns boolean // // Returns true if player "who" has the arrow key "key" currently pressed. // // function GetPlayerKeyAxisState // takes player who, integer whatAxis // returns integer // // Returns -1 for left/down, 0 for middle/none, and 1 for right/up. // The "whatAxis" parameter must be one of the two constants: // KEY_AXIS_HORIZONTAL or KEY_AXIS_VERTICAL // //------------------------------------------------------------------------------ // This library allows you to register functions that will be called when any // player presses or releases any arrow key. The functions must conform to the // KeyEventCallback function interface: // // function interface KeyEventCallback // takes player who, integer whatKey, boolean pressed // returns nothing // // The player parameter is the one who pressed/released the key. // The whatKey integer is the key that was pressed/released. See the key // constants defined above. // The boolean parameter tells you if it was a key press, or a key release that // generated the event. // // function RegisterKeyAction // takes KeyEventCallback callback // returns nothing // // Registers the given KeyEventCallback function to be called when any // player presses any arrow key. Functions can not be unregistered. // //------------------------------------------------------------------------------ // This library also provides a module which will call a predefined method on // all instances of an implementing struct. // // To implement the module in your struct: // implement OnKeyAction // // Your struct must have a method named "onKeyAction" with the same parameter // list and return type of the KeyEventCallback function interface. // // The module also adds an operator for enabling and disabling key events for // single instances of an implementing type. // NOTE!!: Currently, you _must_ enable key events on creation of your struct, // and disable them on destruction. This will become automatic in a future // version. Please, to be forwards-compatible, enable key events in your // struct's .create() method, and disable them in your struct's .destroy() or // .onDestroy() method. // // The operator is: // set myStructInst.keyActionEnabled = true // //============================================================================== // Configuration // =============================================================================
globals // The following constants determines the behaviour of vertical // and horizontal key axis states in the event two opposing // keys are pressed at once. // // If set to true, pressing two opposing keys will cause that // axis' state to be 0. If either key is released, the state of // the axis will represent the key that remains held down. // // If set to false, pressing two opposing keys will cause that // axis' sate to represent the last key pressed. If the key // being represented is released, the state of the axis will // switch to the key that is still held down. private constant boolean ZERO_ON_OPPOSITION_VERTICAL = true private constant boolean ZERO_ON_OPPOSITION_HORIZONTAL = false endglobals
//============================================================================== // End of Configuration // =============================================================================
// ======================================== // Public constants // ========================================
globals constant integer KEY_DOWN = 0 constant integer KEY_UP = 1 constant integer KEY_LEFT = 2 constant integer KEY_RIGHT = 3 constant integer KEY_AXIS_HORIZONTAL = 0 constant integer KEY_AXIS_VERTICAL = 1 endglobals
// ======================================== // Private variables/constants // ========================================
globals // Key event triggers: private trigger key_UP_DOWN = CreateTrigger() private trigger key_UP_UP = CreateTrigger() private trigger key_DOWN_DOWN = CreateTrigger() private trigger key_DOWN_UP = CreateTrigger() private trigger key_LEFT_DOWN = CreateTrigger() private trigger key_LEFT_UP = CreateTrigger() private trigger key_RIGHT_DOWN = CreateTrigger() private trigger key_RIGHT_UP = CreateTrigger() // Key value constants: private constant integer KEY_VALUE_UP = 1 private constant integer KEY_VALUE_DOWN = -1 private constant integer KEY_VALUE_LEFT = -1 private constant integer KEY_VALUE_RIGHT = 1 // Opposition values: private constant integer KEY_OPPOSITE_VALUE_UP = -KEY_VALUE_UP private constant integer KEY_OPPOSITE_VALUE_DOWN = -KEY_VALUE_DOWN private constant integer KEY_OPPOSITE_VALUE_LEFT = -KEY_VALUE_LEFT private constant integer KEY_OPPOSITE_VALUE_RIGHT = -KEY_VALUE_RIGHT // Opposition constants: private constant integer KEY_OPPOSITE_UP = KEY_DOWN private constant integer KEY_OPPOSITE_DOWN = KEY_UP private constant integer KEY_OPPOSITE_LEFT = KEY_RIGHT private constant integer KEY_OPPOSITE_RIGHT = KEY_LEFT // Key-to-axis constants: private constant integer KEY_AXIS_UP = KEY_AXIS_VERTICAL private constant integer KEY_AXIS_DOWN = KEY_AXIS_VERTICAL private constant integer KEY_AXIS_LEFT = KEY_AXIS_HORIZONTAL private constant integer KEY_AXIS_RIGHT = KEY_AXIS_HORIZONTAL // Key axis behaviour constants: private constant boolean KEY_AXIS_ZERO_ON_OP_UP = ZERO_ON_OPPOSITION_VERTICAL private constant boolean KEY_AXIS_ZERO_ON_OP_DOWN = ZERO_ON_OPPOSITION_VERTICAL private constant boolean KEY_AXIS_ZERO_ON_OP_LEFT = ZERO_ON_OPPOSITION_HORIZONTAL private constant boolean KEY_AXIS_ZERO_ON_OP_RIGHT = ZERO_ON_OPPOSITION_HORIZONTAL endglobals
// ======================================== // Key state getters // ========================================
// Individual keys globals private boolean array playerKeyStates endglobals
function GetPlayerKeyState takes player who, integer key returns boolean return playerKeyStates[GetPlayerId(who) + key * 15] endfunction
// Left/Right and Up/Down globals private integer array playerKeyAxisStates endglobals
function GetPlayerKeyAxisState takes player who, integer whatAxis returns integer return playerKeyAxisStates[GetPlayerId(who) + whatAxis * 15] endfunction
// ======================================== // Function events // ========================================
function interface KeyEventCallback takes player who, integer whatKey, boolean pressed returns nothing
globals private KeyEventCallback array callbacks private integer callbackCount = 0 endglobals
function RegisterKeyAction takes KeyEventCallback callback returns nothing set callbacks[callbackCount] = callback set callbackCount = callbackCount + 1 endfunction
//! textmacro KeyAction_HandleFuncEvent takes KEY, DIR, PRESSED private function HandleKeyEventFunc_$KEY$_$DIR$ takes nothing returns boolean local player p = GetTriggerPlayer() local integer pid = GetPlayerId(p) local integer i // Set individual key states set playerKeyStates[KEY_$KEY$ * 15 + pid] = $PRESSED$ // Set axis key states static if $PRESSED$ then static if KEY_AXIS_ZERO_ON_OP_$KEY$ then if playerKeyStates[pid + KEY_OPPOSITE_$KEY$ * 15] then set playerKeyAxisStates[pid + KEY_AXIS_$KEY$ * 15] = 0 else set playerKeyAxisStates[pid + KEY_AXIS_$KEY$ * 15] = KEY_VALUE_$KEY$ endif else set playerKeyAxisStates[pid + KEY_AXIS_$KEY$ * 15] = KEY_VALUE_$KEY$ endif else if playerKeyStates[pid + KEY_OPPOSITE_$KEY$ * 15] then set playerKeyAxisStates[pid + KEY_AXIS_$KEY$ * 15] = KEY_OPPOSITE_VALUE_$KEY$ else set playerKeyAxisStates[pid + KEY_AXIS_$KEY$ * 15] = 0 endif endif // Evaluate registered function callbacks set i = 0 loop exitwhen i == callbackCount call callbacks[i].evaluate(p, KEY_$KEY$, $PRESSED$) set i = i + 1 endloop return false endfunction //! endtextmacro
//! runtextmacro KeyAction_HandleFuncEvent("UP", "DOWN", "true") //! runtextmacro KeyAction_HandleFuncEvent("UP", "UP", "false") //! runtextmacro KeyAction_HandleFuncEvent("DOWN", "DOWN", "true") //! runtextmacro KeyAction_HandleFuncEvent("DOWN", "UP", "false") //! runtextmacro KeyAction_HandleFuncEvent("LEFT", "DOWN", "true") //! runtextmacro KeyAction_HandleFuncEvent("LEFT", "UP", "false") //! runtextmacro KeyAction_HandleFuncEvent("RIGHT", "DOWN", "true") //! runtextmacro KeyAction_HandleFuncEvent("RIGHT", "UP", "false")
// ======================================== // Module events // ========================================
module OnKeyAction private static thistype array all private static integer count = 0 private integer id = 0 method operator keyActionEnabled= takes boolean b returns nothing if b and id == 0 then set all[count] = this set id = count set count = count + 1 elseif id != 0 then set all[id] = all[count] set id = 0 set count = count - 1 endif endmethod //! textmacro KeyAction_HandleEvent takes KEY, DIR, PRESSED private static method handleKeyEvent_$KEY$_$DIR$ takes nothing returns boolean local integer i = 0 loop exitwhen i == count call all[i].onKeyAction(GetTriggerPlayer(), KEY_$KEY$, $PRESSED$) set i = i + 1 endloop return false endmethod //! endtextmacro //! runtextmacro KeyAction_HandleEvent("UP", "DOWN", "true") //! runtextmacro KeyAction_HandleEvent("UP", "UP", "false") //! runtextmacro KeyAction_HandleEvent("DOWN", "DOWN", "true") //! runtextmacro KeyAction_HandleEvent("DOWN", "UP", "false") //! runtextmacro KeyAction_HandleEvent("LEFT", "DOWN", "true") //! runtextmacro KeyAction_HandleEvent("LEFT", "UP", "false") //! runtextmacro KeyAction_HandleEvent("RIGHT", "DOWN", "true") //! runtextmacro KeyAction_HandleEvent("RIGHT", "UP", "false") private static method onInit takes nothing returns nothing //! textmacro KeyAction_AddCondition takes KEY, DIR call TriggerAddCondition(key_$KEY$_$DIR$, Condition(function thistype.handleKeyEvent_$KEY$_$DIR$)) //! endtextmacro //! runtextmacro KeyAction_AddCondition("UP", "DOWN") //! runtextmacro KeyAction_AddCondition("UP", "UP") //! runtextmacro KeyAction_AddCondition("DOWN", "DOWN") //! runtextmacro KeyAction_AddCondition("DOWN", "UP") //! runtextmacro KeyAction_AddCondition("LEFT", "DOWN") //! runtextmacro KeyAction_AddCondition("LEFT", "UP") //! runtextmacro KeyAction_AddCondition("RIGHT", "DOWN") //! runtextmacro KeyAction_AddCondition("RIGHT", "UP") endmethod endmodule
// ======================================== // Initialization // ========================================
private function OnInit takes nothing returns nothing local integer i //! textmacro KeyAction_RegisterEvents takes KEY, DIR set i = 0 loop exitwhen i > 11 // The actual event call TriggerRegisterPlayerEvent(key_$KEY$_$DIR$, Player(i), EVENT_PLAYER_ARROW_$KEY$_$DIR$) // For the functions call TriggerAddCondition(key_$KEY$_$DIR$, Condition(function HandleKeyEventFunc_$KEY$_$DIR$)) set i = i + 1 endloop //! endtextmacro //! runtextmacro KeyAction_RegisterEvents("UP", "DOWN") //! runtextmacro KeyAction_RegisterEvents("UP", "UP") //! runtextmacro KeyAction_RegisterEvents("DOWN", "DOWN") //! runtextmacro KeyAction_RegisterEvents("DOWN", "UP") //! runtextmacro KeyAction_RegisterEvents("LEFT", "DOWN") //! runtextmacro KeyAction_RegisterEvents("LEFT", "UP") //! runtextmacro KeyAction_RegisterEvents("RIGHT", "DOWN") //! runtextmacro KeyAction_RegisterEvents("RIGHT", "UP") endfunction endlibrary this next part is where all the platforming game mechanics are defined. there are also some constants that you can easily play with to change how it works (ie how fast the unit moves, how much of an effect gravity has etc) - Code:
-
scope KeyPressActions initializer Init globals ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Start // Of // Calibration // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constant real TIMESTEP = .015 //the approximate amount of time between each run of GravityActions constant real tOFFSET = 28.0 //how much offset to use when determining terrain type for terrain kill constant real wOFFSET = 20.0 //how much offset to use when determining if you're touching a wall for jumping constant real vJUMPSPEED = 30.0 //default vertical jump speed constant real hJUMPSPEED = 15.0 //default horizontal jump speed constant real GRAVITYCAP = 10.0 //default cap on velocity due to gravity constant real GRAVITYACCEL= .5 //default acceleration due to gravity constant real MOVESPEED = 8.0 //default movespeed ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // End // Of // Calibration // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// public boolean array UseKeyMovement[NumberPlayers] //use regular movement or arrow key movement. if a unit is in ArrowKeyGroup, this variable is true for that player public group ArrowKeyGroup = CreateGroup() //group of units using arrow key movement public unit array ArrowKeyArray[NumberPlayers] //array of the units in above group public trigger KeyMovement = CreateTrigger() //this trigger emulates gravity and keyboard movement public real array YVelocity[NumberPlayers] //this only refers to horizontal movement from jumping, as regular left right movement is constant public real array XVelocity[NumberPlayers] //this only refers to horizontal movement from jumping, as regular left right movement is constant public real array GravityCap[NumberPlayers] //this caps how fast a unit can go due to gravity... this does not cap move speed against gravity public real array MoveSpeed[NumberPlayers] //this determines how fast a unit moves left/right public integer array MoveSteps[NumberPlayers] //how many steps are left to take at that movespeed public real array GravitationalAccel[NumberPlayers] //how strong the effect of gravity is public real array vJumpSpeed[NumberPlayers] //how fast a wall jump is vertically public real array hJumpSpeed[NumberPlayers] //how fast a wall jump is horizontally endglobals private function KeyMovementPeriodic takes nothing returns nothing local unit u = GetEnumUnit() local integer i = GetPlayerId(GetOwningPlayer(u)) //refers the physical position of the unit u local real x = GetUnitX(u) local real y = GetUnitY(u) local integer terrain //this is the change in units vertical position due to gravity set YVelocity[i] = YVelocity[i] - GravitationalAccel[i] //the speed of gravity maxes out at GRAVITYCAP if GravitationalAccel[i] > 0 and YVelocity[i] < -GravityCap[i] then set YVelocity[i] = -GravityCap[i] elseif GravitationalAccel[i] < 0 and YVelocity[i] > GravityCap[i] then set YVelocity[i] = GravityCap[i] endif //call DisplayTextToForce( GetPlayersAll(), "YVelocity: " + R2S(YVelocity[i])) //units position with effect from gravity set y = y + YVelocity[i] set terrain = GetTerrainType(x, y) if terrain != SAFE and terrain != SUPERBOUNCE and terrain != FASTMOVE then call SetUnitPosition(u, x, y) elseif not ((YVelocity[i] * GravitationalAccel[i]) > 0) then set YVelocity[i] = 0 endif //is there horizontal jump movement as well? if XVelocity[i] != 0 then if XVelocity[i] > 0 then set XVelocity[i] = XVelocity[i] - 1 else set XVelocity[i] = XVelocity[i] + 1 endif set x = x + XVelocity[i] endif //is there horizontal arrow key movement? //left arrow key if GetPlayerKeyAxisState(Player(i), KEY_AXIS_HORIZONTAL) == -1 then set x = x - MoveSpeed[i] //right arrow key elseif GetPlayerKeyAxisState(Player(i), KEY_AXIS_HORIZONTAL) == 1 then set x = x + MoveSpeed[i] endif //update unit's position with regard to jump and gravitational forces as well as movement from left/right arrow keys //is point x,y pathable? set terrain = GetTerrainType(x, GetUnitY(u)) if terrain != SAFE and terrain != SUPERBOUNCE and terrain != FASTMOVE then call SetUnitPosition(u, x, GetUnitY(u)) endif set u = null endfunction private function Jump takes player whichPlayer, integer whichKey, boolean pressed returns nothing local integer i = GetPlayerId(whichPlayer) local real x local real y local integer terrain1 local integer terrain2 local integer terrain3 //is the unit using regular movement or arrow key movement? if UseKeyMovement[i] then //up key was pressed if whichKey == 1 and pressed then set x = GetUnitX(ArrowKeyArray[i]) set y = GetUnitY(ArrowKeyArray[i]) set terrain1 = GetTerrainType(x, y + (GravitationalAccel[i] * -wOFFSET)) set terrain2 = GetTerrainType(x - wOFFSET, y) set terrain3 = GetTerrainType(x + wOFFSET, y) if terrain1 == SUPERBOUNCE then call PlatformingAddSpecialTerrain(terrain1, i) elseif terrain2 == SUPERBOUNCE then call PlatformingAddSpecialTerrain(terrain2, i) elseif terrain3 == SUPERBOUNCE then call PlatformingAddSpecialTerrain(terrain3, i) else call PlatformingRemoveSpecialTerrain(pSpecialTerrainTypedx[i], i) endif //regular jump if terrain1 == SAFE or terrain1 == SUPERBOUNCE or terrain1 == FASTMOVE then set YVelocity[i] = GravitationalAccel[i] * vJumpSpeed[i] //wall jump off left-wall elseif terrain2 == SAFE or terrain2 == SUPERBOUNCE or terrain2 == FASTMOVE then set YVelocity[i] = GravitationalAccel[i] * vJumpSpeed[i] set XVelocity[i] = hJumpSpeed[i] //wall jump off right-wall elseif terrain3 == SAFE or terrain3 == SUPERBOUNCE or terrain3 == FASTMOVE then set YVelocity[i] = GravitationalAccel[i] * vJumpSpeed[i] set XVelocity[i] = -hJumpSpeed[i] endif endif endif endfunction //for quick presses of left arrow key private function Left takes player whichPlayer, integer whichKey, boolean pressed returns nothing local integer i = GetPlayerId(whichPlayer) local real x local real y local unit u local integer terrain //is the unit using regular movement or arrow key movement? if UseKeyMovement[i] then //up key was pressed if whichKey == 2 and pressed and (GetPlayerKeyAxisState(Player(i), KEY_AXIS_HORIZONTAL) == -1) then set u = ArrowKeyArray[i] set x = GetUnitX(u) - (MoveSpeed[i] / 6) set y = GetUnitY(u) set terrain = GetTerrainType(x, y) if terrain != SAFE and terrain != SUPERBOUNCE and terrain != FASTMOVE then call SetUnitPosition(u, x, y) endif endif endif set u = null endfunction //for quick presses of right arrow key private function Right takes player whichPlayer, integer whichKey, boolean pressed returns nothing local integer i = GetPlayerId(whichPlayer) local real x local real y local unit u local integer terrain //is the unit using regular movement or arrow key movement? if UseKeyMovement[i] then //up key was pressed if whichKey == 3 and pressed and (GetPlayerKeyAxisState(Player(i), KEY_AXIS_HORIZONTAL) == 1) then set u = ArrowKeyArray[i] set x = GetUnitX(u) + (MoveSpeed[i] / 6) set y = GetUnitY(u) set terrain = GetTerrainType(x, y) if terrain != SAFE and terrain != SUPERBOUNCE and terrain != FASTMOVE then call SetUnitPosition(u, x, y) endif endif endif set u = null endfunction private function KeyMovementInit takes nothing returns nothing call ForGroup(ArrowKeyGroup, function KeyMovementPeriodic) endfunction private function Init takes nothing returns nothing local integer i = 0 call DisableTrigger(KeyMovement) call TriggerRegisterTimerEvent(KeyMovement, TIMESTEP, true) call TriggerAddAction( KeyMovement, function KeyMovementInit) call RegisterKeyAction(Jump) call RegisterKeyAction(Left) call RegisterKeyAction(Right) loop exitwhen i >= NumberPlayers set YVelocity[i] = 0 set XVelocity[i] = 0 set GravitationalAccel[i] = GRAVITYACCEL set UseKeyMovement[i] = false set vJumpSpeed[i] = vJUMPSPEED set hJumpSpeed[i] = hJUMPSPEED set MoveSpeed[i] = MOVESPEED set GravityCap[i] = GRAVITYCAP set i = i + 1 endloop endfunction endscope this last section creates the units that will be platforming. it includes triggers to start and stop platforming for whatever player (the unit which is platforming will always stay the same, although you could easily change that with a bit of hacking) - Code:
-
globals integer NumberPlayers = 8 //number of players in your map real pSPAWNX = 0 //where the unit will spawn (x-coordinate) real pSPAWNY = 0 //where the unit will spawn (y-coordinate) integer pUNITID = 'ewsp' //the integer ID value of whatever unit type you want to use camerasetup array PlatformingCameras[NumberPlayers] endglobals
library PlatformingAux initializer PlatformingAuxInit //starts platforming for player i function StartPlatforming takes integer i returns nothing //adds the plat unit to the platforming movement group. this group controls its units with arrow keys call GroupAddUnit(KeyPressActions_ArrowKeyGroup, KeyPressActions_ArrowKeyArray[i]) set KeyPressActions_UseKeyMovement[i] = true //enables the arrow key trigger... an expensive trigger so should only be active when necessary if NumberPlatforming == 0 then call EnableTrigger(KeyPressActions_KeyMovement) endif set NumberPlatforming = NumberPlatforming + 1 //activates the platforming camera initial setup... does not periodically reset the camera if GetLocalPlayer() == Player(i) then call SetCameraTargetController(KeyPressActions_ArrowKeyArray[i], 0, 0, false) call CameraSetupSetField(PlatformingCameras[i], CAMERA_FIELD_ANGLE_OF_ATTACK, 270, 0) call CameraSetupSetField(PlatformingCameras[i], CAMERA_FIELD_TARGET_DISTANCE, 2200, 0) call CameraSetupApply(PlatformingCameras[i], false, false) endif //unhides the wisp call ShowUnit(KeyPressActions_ArrowKeyArray[i], true) endfunction //stops platforming for player i function StopPlatforming takes integer i returns nothing
//removes the plat unit to the platforming movement group. this group controls its units with arrow keys call GroupRemoveUnit(KeyPressActions_ArrowKeyGroup, KeyPressActions_ArrowKeyArray[i]) set KeyPressActions_UseKeyMovement[i] = false //updates the number of units platforming/regular mazing set NumberPlatforming = NumberPlatforming - 1 //disables the arrow key trigger when not in use if NumberPlatforming == 0 then call DisableTrigger(KeyPressActions_KeyMovement) call DisableTrigger(gg_trg_Game_Loop_Platforming) endif //hides the platforming unit call ShowUnit(KeyPressActions_ArrowKeyArray[i], false) //resets the game camera if GetLocalPlayer() == Player(i) then call ResetToGameCamera(.5) endif endfunction function PlatformingAuxInit takes nothing returns nothing local integer i = 0 loop exitwhen i >= NumberPlayers if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then set PlatformingCameras[i] = CreateCameraSetup() set KeyPressActions_ArrowKeyArray[i] = CreateUnit(i, pUNITID, pSPAWNX, pSPAWNY, 0) call ShowUnit(KeyPressActions_ArrowKeyArray[i], false) endif set i = i + 1 endloop endfunction endlibrary
to use the next few you need everything in this spoiler (not to mention theyre very useful on their own - Spoiler:
- Code:
-
library ListModule //=========================================================================== // Information: //============== // // This library provides the List module, which allows you to easily create // a linked list of all of the allocated instances of a struct-type. Iterating // through a linked list is about 12% faster than iteratating through an array // in JASS. There is no faster method to iterate through a list of structs than // the method used by this module. Aside from the marginal speed gain, the best // use of this library is to hide some ugly low-level code from your structs. // Rather than manually building and maintaining a list of struct instances, // just implement the List module, and your code will become much prettier. // //=========================================================================== // How to use the List module: //============================= // // Using the List module is pretty simple. First, implement it in your // struct (preferably at the top to avoid unnecessary TriggerEvaluate calls). // In the struct's create method, you must call listAdd(). In the onDestroy // method, you must also call listRemove(). An example is shown below:
/* struct Example implement List static method create takes nothing returns Example local Example this = allocate() call listAdd() //This method adds the instance to the list. return this endmethod method onDestroy takes nothing returns nothing call listRemove() //This method removes the instance from the list. endmethod endstruct */ // The requirement to call listAdd() and listRemove() will be done away // with once JassHelper supports module onDestroy and module onCreate, but // for now, it is not too much of a burden. // // Once this is done, your struct will gain all of the methods detailed // in the API section. Below is an example of how to iterate through the list // of allocated structs of the implementing struct-type: /* function IterationExample takes nothing returns nothing local Example e = Example.first loop exitwhen e == 0 //Do something with e here. set e = e.next endloop //Use .last and .prev instead to iterate backwards. endmethod */ // //=========================================================================== // List module API: //================== // // (readonly)(static) first -> thistype // This member contains the first instance of thistype in the list. // // (readonly)(static) last -> thistype // This member contains the last instance of thistype in the list. // // (readonly)(static) count -> integer // This member contains the number of allocated structs of thistype. // // (readonly) next -> thistype // This member contains the next instance of thistype in the list. // // (readonly) prev -> thistype // This member contains the previous instance of thistype in the list. // // listAdd() // This method adds this instance to the list of structs of thistype. // This should be called on each instance after it is allocated (within // the create method). // // listRemove() // This method removes this instance from the list of structs of thistype. // This should be called on each instance before it is destroyed (within // the onDestroy method). // // (static) listDestroy() // This method destroys all the structs of thistype within the list. // //===========================================================================
module List private static boolean destroying = false private boolean inlist = false readonly static integer count = 0 readonly thistype next = 0 readonly thistype prev = 0 static method operator first takes nothing returns thistype return thistype(0).next endmethod static method operator last takes nothing returns thistype return thistype(0).prev endmethod method listRemove takes nothing returns nothing if not inlist then return endif set inlist = false set prev.next = next set next.prev = prev set count = count - 1 endmethod
method listAdd takes nothing returns nothing if inlist or destroying or this==0 then return endif set inlist = true set last.next = this set prev = last set thistype(0).prev = this set next = thistype(0) set count = count + 1 endmethod static method listDestroy takes nothing returns nothing local thistype this = last set destroying = true loop exitwhen this == 0 call destroy() set this = prev endloop set destroying = false endmethod endmodule
endlibrary
- Code:
-
library locust
//indentation is wrong because I made the functions before knowing libraries existed
//adds flexible locust to unit u function AddUnitLocust takes unit u returns nothing call UnitAddAbility( u, 'Aloc') call ShowUnit(u, false) call ShowUnit(u , true) endfunction
//adds flexible locust to last created unit function AddLastUnitLocust takes nothing returns nothing call UnitAddAbility( bj_lastCreatedUnit, 'Aloc') call ShowUnit(bj_lastCreatedUnit, false) call ShowUnit(bj_lastCreatedUnit, true) endfunction
//Will show dead hidden heroes function AddEnumLocust takes nothing returns nothing local unit u = GetEnumUnit() call UnitAddAbility( u, 'Aloc') call ShowUnit(u, false) call ShowUnit(u, true) set u = null endfunction
//this destroys a boolexpr, DONT USE function AddLocustPlayerInit takes player p returns nothing local group units = CreateGroup() call GroupEnumUnitsOfPlayer(units, p, NotMazer) call ForGroup(units, function AddEnumLocust) call DestroyGroup(units) set units = null endfunction
function AddLocustAll takes nothing returns nothing local group units = CreateGroup() call GroupEnumUnitsInRect(units, GetWorldBounds(), NotMazer) call ForGroup(units, function AddEnumLocust) call DestroyGroup(units) set units = null endfunction
endlibrary
Super Easy Extremely Customizable Wisp Wheel - Spoiler:
- Code:
-
library WispWheel requires ListModule, locust
globals //the time interval used for each periodic call on Wheel.rotate private constant real wTIMESTEP = .05 //maximum number of spokes supported //the less the better, but never less then used in any wheel private constant integer wNUMSPOKES = 20 //the timer used for all wisp wheels private timer wTimer = CreateTimer() endglobals
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Wheel Struct // by Serenity09 // Clan TMMM US EAST // Credits to grim001 for ListModule // and Anitarf and Pat1487 for help // // to create a Wheel: // SimpleWheel.create(unit <centerunit>, player <player owner>, integer <spoke unit ID>, integer <numspokes>, integer <spokelength>, real <degbetween>, real <distbetween>, real <angvelocity>) // distbetween should be somewhere from 100 to 1000, situation depending. angvelocity is very slow around 10 and very fast around 30. zheight is nonexistant at 0 and very high at 600 // center unit: is the center of the wheel. this unit may move and the wheel will follow it // spoke unit ID: the integer ID for the unit that composes the wheel // num spokes: the number of spokes in a wheel (may not exceed wNUMSPOKES) // spoke length: the number of units of the matching ID in each spoke // deg between: the amount of degrees between each spoke (does not include the degrees between the last spoke and the first on purpose) // dist between: the distance between each unit in a spoke // ang velocity: the rate at which a wheel turns. a negative value will make the wheel turn counter clockwise (possitive vice-versa) // // If you want to have some spokes periodically fly, then you must use // AdvancedWheel.create(unit <centerunit>, player <player owner>, integer <spoke unit ID>, integer <numspokes>, integer <spokelength>, real <degbetween>, real <distbetween>, real <angvelocity>, real <zheight>, real <zrate>, real <zoffset>) // The only difference is the addition of three z parameters // z height: if you want the wheel fly at certain angles, this is the value to use (by default wheels will not fly) // z rate: controls how many spokes are flying at once // z offset: controls where wisps start flying (given in degrees) // If the wheel does not use the z parameters, you should just use simple wheel, it is more efficient for a non flying wheel // // To make a wheel rotate: // create a wheel (either simple or advanced) and store it as a variable (global) and it will rotate automatically on creation // do not destroy wheels, as there is no way to destroy hashtables // instead just pause and unpause that wheel using <yourwheel>.wStart() and <yourwheel>.wStop() // // to import into a map // import the ListModule library by grim001 and this WispWheel library, make sure to use the ListModule with fix by Anitarf // thats it, the Wheel struct is ready to go // this will create conflicts if you have any other struct named SimpleWheel/AdvancedWheel, or the global variables wTIMESTEP/wNUMSPOKES/wTimer are already in use // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct SimpleWheel readonly unit center
readonly integer nSpoke readonly integer nSpokeLength readonly integer unitID
readonly real degBetween readonly real distBetween readonly real angVelocity readonly player owner readonly hashtable units readonly real array degrees[wNUMSPOKES] implement List public stub method rotate takes nothing returns nothing local integer i = 1 local integer j = 1 local unit u local real x local real y local real distFromCent //how much the angle should change with each run of the periodic local real dtheta = wTIMESTEP * angVelocity local real thetaOld local real thetaNew local real r
loop exitwhen i > nSpoke //every unit in the same spoke should make the same angle with the center. every spoke has at least 1 unit set thetaOld = this.degrees[i] //the new angle is given by the old angle + the change in angle per every time step set thetaNew = thetaOld + dtheta //prevents bloated reals if thetaNew < 360 then set this.degrees[i] = thetaNew else set this.degrees[i] = thetaNew - 360 endif //the angle in radians set r = thetaNew * bj_PI / 180 loop exitwhen j > nSpokeLength //dist from center is linear set distFromCent = j * distBetween //the new x and y value for the unit after the change set x = GetUnitX(this.center) + Cos(r) * distFromCent set y = GetUnitY(this.center) + Sin(r) * distFromCent //the current unit being moved in the wheel //set u = LoadUnitHandleBJ(i, j, this.units) set u = LoadUnitHandle(this.units, i, j) //actually moving the unit call SetUnitX(u, x) call SetUnitY(u, y) set j = j + 1 endloop //reset j set j = 1 set i = i + 1 endloop set u = null endmethod private static method wPeriodic takes nothing returns nothing local SimpleWheel e = .first loop exitwhen e == 0 call e.rotate() set e = e.next endloop endmethod public method wUnpause takes nothing returns nothing if .count == 0 then call TimerStart(wTimer, wTIMESTEP, true, function SimpleWheel.wPeriodic) endif call .listAdd() endmethod public method wPause takes nothing returns nothing call .listRemove() if .count == 0 then call PauseTimer(wTimer) endif endmethod public method GetUnitInWheel takes integer spokenum, integer wispnum returns unit return LoadUnitHandle(this.units, spokenum, wispnum) endmethod static method create takes unit centerunit, player powner, integer spokeunitID, integer numspokes, integer spokelength, real degreesbetween, real distbetween, real angvelocity returns SimpleWheel local SimpleWheel newwheel = SimpleWheel.allocate() local integer i = 1 local integer j = 1 local real deg local real dist local real x local real y local real r local unit u set newwheel.center = centerunit set newwheel.unitID = spokeunitID set newwheel.owner = powner set newwheel.nSpoke = numspokes set newwheel.nSpokeLength = spokelength set newwheel.degBetween = degreesbetween set newwheel.distBetween = distbetween set newwheel.angVelocity = angvelocity set newwheel.units = InitHashtable() loop exitwhen i > newwheel.nSpoke set deg = i*newwheel.degBetween set newwheel.degrees[i] = deg set r = deg * bj_PI / 180 loop exitwhen j > newwheel.nSpokeLength set dist = j*newwheel.distBetween set x = GetUnitX(newwheel.center) + Cos(r) * dist set y = GetUnitY(newwheel.center) + Sin(r) * dist set u = CreateUnit(newwheel.owner, newwheel.unitID, x, y, 0) call SetUnitInvulnerable(u, true) call AddUnitLocust(u) call SaveUnitHandle(newwheel.units, i, j, u) set j = j + 1 endloop set j = 1 set i = i + 1 endloop //call TimerStart(wTimer, wTIMESTEP, true, function SimpleWheel.wPeriodic) //call newwheel.listAdd() set u = null return newwheel endmethod endstruct
struct FlyingWheel extends SimpleWheel //internal variables for each AdvancedWheel (in addition to those from SimpleWheel) private real zHeight private real zRate private real zOffset public method rotate takes nothing returns nothing local integer i = 1 local integer j = 1 local unit u local real x local real y local real distFromCent local real dtheta = wTIMESTEP * angVelocity local real thetaOld local real thetaNew local real r
loop exitwhen i > this.nSpoke set thetaOld = this.degrees[i] set thetaNew = thetaOld + dtheta if thetaNew < 360 then set this.degrees[i] = thetaNew else set this.degrees[i] = thetaNew - 360 endif set r = thetaNew * bj_PI / 180 loop exitwhen j > this.nSpokeLength set distFromCent = j * this.distBetween set x = GetUnitX(this.center) + Cos(r) * distFromCent set y = GetUnitY(this.center) + Sin(r) * distFromCent set u = LoadUnitHandle(this.units, i, j) call SetUnitX(u, x) call SetUnitY(u, y) //if z height is enabled this is changed call SetUnitFlyHeight(u, this.zHeight * Sin((r * this.zRate) + (this.zOffset * bj_PI / 180)), 0) set j = j + 1 endloop set j = 1 set i = i + 1 endloop set u = null endmethod //center, player, unitID, numspoke, length, degbet, distbet, angveloc, zheight static method create takes unit centerunit, player powner, integer spokeunitID, integer numspokes, integer spokelength, real degreesbetween, real distbetween, real angvelocity, real zheight, real zrate, real zoffset returns FlyingWheel local FlyingWheel newwheel = FlyingWheel.allocate(centerunit, powner, spokeunitID, numspokes, spokelength, degreesbetween, distbetween, angvelocity)
set newwheel.zHeight = zheight set newwheel.zRate = zrate set newwheel.zOffset = zoffset return newwheel endmethod
endstruct
endlibrary
This creates a really easy mortar n target, which fires randomly avoiding whatever terrain type is declared as IllegalTerrainType in the globals - Spoiler:
- Code:
-
library MnT requires ListModule, locust
globals //how long to wait between firing each mortar... must be synced with object editor to prevent multiple shots private constant real MnTTimeStep = 2.2 //timer used for all MnT pairs private timer MnTTimer = CreateTimer() //the target cannot be placed on this terrain type private constant integer IllegalTerrainType = 'Oaby' //outland Abyss (cliff) change this to whatever endglobals
///////////////////////////////////////////////////////////////////////////////////////////////////////////// // Mortar And Target Struct // by Serenity09 // Clan TMMM US East // // Purpose: Creates a mortar and target pair that is easy to keep track of. // Consolidates all code into creating the pair and then periodically calling // MnTActions in order to randomly move the target within the confines and order // the Mortar to attack it. // // To create: create a way to reference the mortar/target pair after creation (such as a global variable) // Instantiate the struct using .create() // Ex. local MortarNTarget lvl2Mortar = MortarNTarget.create(int <mortarID>, int <targetID>, player <playerID>, rect <mortarrect>, rect <targetrect>) // mortarID is the integer data value for the unit to be used as the mortar // targetID is the integer data value for the unit to be used as the target // playerID is who will own the mortar and target // mortarrect is the rect in which the mortar will be created // targetrect is the boundaries within which the target will randomly move (teleport style) // // To issue the standard MnTActions to that mortar just call MnTActions on it // Ex. call lvl2Mortar.MnTActions() // // Unlike wispwheels, you should destroy mortars when not in use (mortars dont use hashes) // When you destroy a mortar/target with .destroy(), .onDestroy() will automatically be called // .onDestroy() removes the mortar/target and nulls the unit member variables for that instance. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct MortarNTarget //member variables readonly unit Mortar readonly unit Target private real minX private real maxX private real minY private real maxY implement List public method MnTActions takes nothing returns nothing local real newX local real newY loop set newX = GetRandomReal(this.minX, this.maxX) set newY = GetRandomReal(this.minY, this.maxY) exitwhen (GetTerrainType(newX, newY) != IllegalTerrainType) endloop //move the target randomly within its given boundaries call SetUnitX(Target, newX) call SetUnitY(Target, newY) //order the mortar to attack the target call IssuePointOrder(this.Mortar, "attackground", GetUnitX(this.Target), GetUnitY(this.Target)) endmethod /* private method MnTCreateWheel takes unit center, player owner, integer unitID, integer numspoke, integer spokel, real degbet, real distbet, real angvel returns nothing local SimpleWheel newWheel = SimpleWheel.create(center, owner, unitID, numspoke, spokel, degbet, distbet, angvel) call UnitRemoveAbility(center, 'Apiv') call DestroyTrigger(GetTriggeringTrigger()) endmethod public method MnTWispShot takes player owner, integer unitID, integer numspoke, integer spokel, real degbet, real distbet, real angvel returns nothing local unit u local trigger onProjLand = CreateTrigger() call SetUnitX(Target, GetRandomReal(this.minX, this.maxX)) call SetUnitY(Target, GetRandomReal(this.minY, this.maxY)) set u = CreateUnit(owner, unitID, GetUnitX(this.Target), GetUnitY(this.Target), 0) call UnitAddAbility(u, 'Apiv') call TriggerRegisterUnitEvent(onProjLand, u, EVENT_UNIT_DEATH) call TriggerAddAction(onProjLand, function MnTCreateWheel(u, owner, unitID, numspoke, spokel, degbet, distbet, angvel)) set onProjLand = null set u = null endmethod */ private static method MnTPeriodic takes nothing returns nothing //use of thistype because it might not be called by a simple wheel local MortarNTarget e = .first loop exitwhen e == 0 call e.MnTActions() set e = e.next endloop endmethod public method MnTUnpause takes nothing returns nothing if .count == 0 then call TimerStart(MnTTimer, MnTTimeStep, true, function MortarNTarget.MnTPeriodic) endif call .listAdd() endmethod public method MnTPause takes nothing returns nothing call IssueImmediateOrder(Mortar, "stop") call .listRemove() if .count == 0 then call PauseTimer(MnTTimer) endif endmethod
method onDestroy takes nothing returns nothing //runs when MortarNTarget.destroy() is called call RemoveUnit(Mortar) call RemoveUnit(Target) call .listRemove() if .count == 0 then call PauseTimer(MnTTimer) endif set Mortar = null set Target = null endmethod static method create takes integer mortarID, integer targetID, player playerID, rect mortarloc, rect targetrect returns MortarNTarget //allocate memory for the mortar and target local MortarNTarget new = MortarNTarget.allocate() //create the mortar and target set new.Mortar = CreateUnit(playerID, mortarID, GetRectCenterX(mortarloc), GetRectCenterY(mortarloc), 0) set new.Target = CreateUnit(playerID, targetID, GetRectCenterX(targetrect), GetRectCenterY(targetrect), 0) call AddUnitLocust(new.Mortar) call AddUnitLocust(new.Target) set new.minX = GetRectMinX(targetrect) set new.maxX = GetRectMaxX(targetrect) set new.minY = GetRectMinY(targetrect) set new.maxY = GetRectMaxY(targetrect) return new endmethod endstruct
endlibrary
here are some more widely used triggers for... Easy Patrols: - Spoiler:
- Code:
-
library easyPatrols requires locust
function CreateAndPatrolReal takes real x1, real y1, real x2, real y2, integer unitID, player playerID returns nothing local unit u = CreateUnit(playerID, unitID, x1, y1, 0) call IssuePointOrder(u, "patrol", x2, y2) call AddUnitLocust(u) set u = null endfunction
function CreateAndPatrolLoc takes location l1, location l2, integer unitID, player playerID returns nothing local unit u = CreateUnitAtLoc(playerID, unitID, l1, 0) call IssuePointOrder(u, "patrol", GetLocationX(l2), GetLocationY(l2)) call AddUnitLocust(u) set u = null endfunction
//Creates a unit at the center of r1 and has it patrol to the center of r2 function CreateAndPatrolCenterRect takes rect r1, rect r2, integer unitID, player playerID returns nothing local unit u = CreateUnit(playerID, unitID,GetRectCenterX(r1), GetRectCenterY(r1), 0) call IssuePointOrder(u, "patrol", GetRectCenterX(r2), GetRectCenterY(r2)) call AddUnitLocust(u) set u = null endfunction
//creates a unit at a random point in r1 and orders it to patrol to a random point in r2 function CreateAndPatrolRandomRect takes rect r1, rect r2, integer unitID, player playerID returns nothing local real x1 = GetRandomReal(GetRectMinX(r1), GetRectMaxX(r1)) local real y1 = GetRandomReal(GetRectMinY(r1), GetRectMaxY(r1)) local real x2 = GetRandomReal(GetRectMinX(r2), GetRectMaxX(r2)) local real y2 = GetRandomReal(GetRectMinY(r2), GetRectMaxY(r2)) local unit u = CreateUnit(playerID, unitID, x1, y1, GetRandomReal(0, 360)) call IssuePointOrder(u, "patrol", x2, y2) call AddUnitLocust(u) set u = null endfunction
endlibrary
Easy Mass Random Creates - Spoiler:
- Code:
-
library easyMove requires locust
function MassCreate takes rect r, real moveAngleDeg, real dist, integer unitID, player playerID returns nothing local real x = GetRandomReal(GetRectMinX(r), GetRectMaxX(r)) local real y = GetRandomReal(GetRectMinY(r), GetRectMaxY(r)) //unit faces away from the direction it will travel local unit u = CreateUnit(playerID, unitID, x, y, moveAngleDeg + 180) local real moveAngleRad = (moveAngleDeg / 180) * bj_PI call IssuePointOrder(u, "move", x + dist * Cos(moveAngleRad), y + dist * Sin(moveAngleRad)) call AddUnitLocust(u) set u = null endfunction
function CreateNMove takes rect r1, rect r2, integer unitID, player playerID returns nothing local real x1 = GetRectCenterX(r1) local real y1 = GetRectCenterY(r1) local real x2 = GetRectCenterX(r2) local real y2 = GetRectCenterY(r2) local unit u = CreateUnit(playerID, unitID, x1, y1, 0) call IssuePointOrder(u, "move", x2, y2) call AddUnitLocust(u) set u = null endfunction
//orders entering unit to move to rect r2 function NextMove takes rect r returns nothing call IssuePointOrder(GetTriggerUnit(), "move", GetRectCenterX(r), GetRectCenterY(r)) endfunction
function UnitNextMove takes rect r, unit u returns nothing call IssuePointOrder(u, "move", GetRectCenterX(r), GetRectCenterY(r)) endfunction
endlibrary
thats enough for now... the most useful trigger would probably be the terrain effects thing. but thats also definitely the hardest to import / explain how it works so if you want that just open the map and try taking it... or more likely delete everything but that link to map download | |
|