|
 |
| Author |
Message |
|
Pawz
|
Posted: 24 Mar, 2008
|
|
Joined: 15 Feb, 2007 Posts: 599 Location: Rockingham, Australia
|
|
Ok we've got the sticky for useful threads which I'm trying to keep up to date, and Manimal did suggest that a 'Script Toolbox' type thread would be useful, so, here it is.
Please post any helpful / handy scripts you currently use in your mod that solve various problems you've bumped into. Try to keep it short, to the point, and stripped of as much mod-related code as possible, to make it easy for the rest of us to just pick it up & use it.
Please use 1 post per script, so I can link each one to the list here:
How to find the path of your mod
How to pass data from sim to ui and back
How to selectively enable console commands in your mod (aka allowing 'cheat' type commands)
_________________ We are Supremilated
www.supremilated.com
Last edited by Pawz on 03 Mar, 2010, edited 3 times in total.
|
|
| Top |
|
 |
|
Pawz
|
Posted: 24 Mar, 2008
|
|
Joined: 15 Feb, 2007 Posts: 599 Location: Rockingham, Australia
|
To get it started I'll post Manimal's handy script for finding the path to your mod.
Manimal wrote: I noticed that you're naming explicitly the path to your mod. Here is my little handy script that is subject to enhancements in a close future : In case you need to get "dynamicaly" the path where your mod is currently installed in : Code: --[[################################################################################]]-- --[[# #]]-- --[[# File : /hook/lua/modlocator.lua #]]-- --[[# #]]-- --[[# Author : GPG Devs + Manimal #]]-- --[[# #]]-- --[[# Version : 1 #]]-- --[[# #]]-- --[[# Revision : 10 mars 2008 #]]-- --[[# #]]-- --[[# Summary : Mod Location scripts. #]]-- --[[# #]]-- --[[# Copyright : © 2008 Gas Powered Games, Inc. & Manimal All rights reserved. #]]-- --[[# #]]-- --[[################################################################################]]--
-- given a MOD UID , returns mod location
local function GetActiveModLocation( mod_Id ) for i, mod in __active_mods do if mod_Id == mod.uid then LOG("MANIMAL\'s MOD LOCATOR INFO: Active Mod Found (name="..(mod.name or 'unknown')..", UID="..(mod.uid or 'none')..", location = "..mod.location..") .") return mod.location end end -- Signaler Echec ! LOG("MANIMAL\'s MOD LOCATOR WARNING: Unable to get Mod Location ! Wrong or missing UID.") return {} end use it like this : Code: myModLocation = GetActiveModLocation("1234-5678-9012-3456") if myModLocation then import(myModLocation..'/lua/myScript.lua') --this should be defaulted when there is a missing mod location end
Quiet simple and functional !  Note that the UID is fictive in this example, you need your own UIDSee /mohodata/lua/mods.lua for more informations.
Manimal - feel free to post this again, with your own code so you can edit etc - I'm just borrowing this to get the toolbox started, if you will 
_________________ We are Supremilated
www.supremilated.com
|
|
| Top |
|
 |
|
Pawz
|
Posted: 24 Mar, 2008
|
|
Joined: 15 Feb, 2007 Posts: 599 Location: Rockingham, Australia
|
NovaPrim3 wrote: Thanks for that Chirmaya, I saw a similar post by you with the 'LoadSilverPetals' thing, but I've finally managed to get my head around it. I'm going to summarise Sim to UI and UI to Sim data transfers, in a situation that has nothing to do with maps or units. Hope this helps. --- SIM LAYER -- /lua/someSim.lua Code: # You'd generally call this function as a thread from /hook/lua/simInit.lua function mainThread() # send data to UI Sync.SomeData = "Hello UI" end
function fromUI(args) # receiving data from the UI print(args) end
/hook/lua/SimCallbacks.lua Code: Callbacks.SendToSim = import('/mods/ModName/lua/someSim.lua').fromUI
--- UI LAYER --- /modules/someModule.lua Code: function someButtonClick() SimCallback( { Func = "SendToSim", Args = "Hello Sim" } ) end
function fromSim(args) # receiving data from the Sim print(args) end
/hook/lua/UserSync.lua Code: local baseOnSync = OnSync
function OnSync() baseOnSync()
if Sync.SomeData then import('/mods/ModName/modules/someModule.lua').fromSim(Sync.SomeData) end end
That's it, for the hooked files, /hook/lua/SimCallbacks.lua /hook/lua/UserSync.lua that's all you need in them, remembering they are hooked so there is more behind them. Your module file and your sim file of course will have a lot more to them. If you want to pass more than one argument between the sim and UI, use arrays (as Chirmaya was doing above), ie: Sync.SomeData = { "Hello", "World } Good luck!
_________________ We are Supremilated
www.supremilated.com
|
|
| Top |
|
 |
|
spliff
|
Posted: 03 Apr, 2008
|
|
| Forum Scout |
 |
 |
Joined: 18 Feb, 2007 Posts: 493 Location: Gone
|
Below is a new version of my selective cheats code that Pawz posted earlier. He is going to remove that copy so I can keep this one updated.
Detect if mod is running under FA. Useful if you want to write code that works in both versions
Code: -- Set global variable FA to true if we are playing Forged Alliance FA = string.sub(GetVersion(),1,3) == '1.5'
Selectively activating cheats (requires FA variable above). This code is designed for when you need some cheats to work but not others. Cheating must still be enabled in the lobby before the game starts.Code: -- if one of these strings appears anywhere in the command string it is a cheat cheatStrings = { 'setfocusarmy', 'createentity', 'createunit', 'copy', 'add', 'blingbling', 'sallyshears', 'sim', 'execute', 'teleport', 'destroy', 'kill', 'ai_', }
function IsCheat( cmd ) -- returns false or the position a cheat was found (true) local cheatFound = false if cmd then cmd = string.lower(cmd) for _,cheat in cheatStrings do cheatFound = string.find( cmd , cheat ) if cheatFound then break end end end return cheatFound end
-- CATCH CONSOLE CHEATERS local oldConExecute = ConExecute function ConExecute( cmd ) if IsCheat( cmd ) then print('Haa ha! You tried to cheat and I stopped you.') else oldConExecute( cmd ) end end
local oldConExecuteSave = ConExecuteSave function ConExecuteSave( cmd ) if IsCheat( cmd ) then print('Haa ha! You tried to cheat and I stopped you.') else oldConExecuteSave( cmd ) end end
-- STOP KEYBINDING CHEATERS local oldIN_AddKeyMapTable = IN_AddKeyMapTable function IN_AddKeyMapTable(keyMapTable) -- remove keys that activate cheats LOG('Clearing cheats from added keymap.') local newKeyMapTable = {} for key,data in keyMapTable do if IsCheat( data.action ) then LOG('Keybinding ['..key..'] = '..data.action..' removed because it contains a cheat.') else newKeyMapTable[key] = data end end oldIN_AddKeyMapTable( newKeyMapTable ) end
-- REMOVE BOUND CHEATS if FA then IN_ClearKeyMap() -- Add back all mapped keys and user prefs except cheats IN_AddKeyMapTable(import('/lua/keymap/keymapper.lua').GetKeyMappings(false)) else -- Remove all debug keys first local debugKeyMap = import('/lua/keymap/defaultKeyMap.lua').debugKeyMap IN_RemoveKeyMapTable(debugKeyMap) -- Now add them back with just the cheats removed IN_AddKeyMapTable(debugKeyMap) end
_________________ I have left the community. To adopt one of my mods (Advanced Coop, Multiplayer Save, Advanced AI) or tools (Advanced Utils, Mod System Patch, Mod Installer) please PM me or visit http://warriorhut.org/forged_alliance
|
|
| Top |
|
 |
|
Manimal
|
Posted: 29 Apr, 2008
|
|
Joined: 11 Apr, 2007 Posts: 1915
|
Thank you Pawz !
Here is the handy script that allows to get any NEW textures to show up ingame, such as strategic icons and new panels (for referencen, see my functional scripts+textures in SupCivs), in a very conveninent way as you won't have to tell the script where it is located !
WARNING:
I do not recommend this method for compatibility reasons. Enabling the shadow folder could cause textures from other mod to be overwritten. There is no way to know what mod will overwrite another mod, and in which order this will occur...
[SC][FA] Data Path Mount Points script
This is a revised version that works so great since I added a very simple test to my previous release.
The main great advantage is that you won't need to alter a single line of the scripts in order your mod show up your own strategic icons and other home cooked textures !
Keeping this version of SupComDataPath.lua should not bring conflicts between mods.
You can leave it "on" permanently in the bin folder, it won't cause any troubles even with no mods enabled+selected.
Please support my patch request that concerns this file among others.
Code: --[[################################################################################ # # # File : Forger Alliance/bin/SupComDataPath.lua # # # # Author : GPG Devs + Manimal # # # # Version : 1 # # # # Revision : 28 avril 2008 # # # # Summary : Data Path Mount Points script. # # # # Copyright : © 2007 Gas Powered Games, Inc. & Manimal All rights reserved. # # # ################################################################################]]--
path = {}
local function mount_dir( dir, mountpoint ) table.insert(path, { dir = dir, mountpoint = mountpoint } ) end
local function mount_contents(dir, mountpoint)
LOG('checking ' .. dir)
for _,entry in io.dir(dir .. '\\*') do if entry != '.' and entry != '..' then
local mp = string.lower(entry)
# string.gsub ( string, pattern-to-find-in-string, substitution-string ) mp = string.gsub( mp, '[.]scd$', '' ) mp = string.gsub( mp, '[.]zip$', '' )
mount_dir( dir .. '\\' .. entry, mountpoint .. '/' .. mp )
# Added here the missing mountpoints if mountpoint== '/mods' then mount_dir( dir .. '\\' .. entry .. '\\textures', '/textures' ) end; end end end
mount_contents(SHGetFolderPath('PERSONAL') .. 'My Games\\Gas Powered Games\\Supreme Commander Forged Alliance\\mods', '/mods') mount_contents(SHGetFolderPath('PERSONAL') .. 'My Games\\Gas Powered Games\\Supreme Commander Forged Alliance\\maps', '/maps')
mount_dir(InitFileDir .. '\\..\\gamedata\\*.scd', '/') mount_dir(InitFileDir .. '\\..', '/')
hook = { '/hook', '/schook' }
protocols = { 'http', 'https', 'mailto', 'ventrilo', 'teamspeak', 'daap', 'im', }
_________________ Console Plus - Solo A.C.U. - Experimental Wars
Last edited by Manimal on 31 Jan, 2009, edited 4 times in total.
|
|
| Top |
|
 |
|
Manimal
|
Posted: 01 Aug, 2008
|
|
Joined: 11 Apr, 2007 Posts: 1915
|
[FA] Adjacency Check Revisited
I found among some other script parts that function AdjacencyCheck from lua/editor/UnitCountBuildConditions.lua works on a unit ID, and it's uniquely the UEF ones on the top !!!
You could get an error poping out even if your work is correct.
So I rewrote it for my own use in a more abstracted way, by using the existing data that are stored in BuildingTemplates.
By using my little fixture below, this will occur no more as it works with the related faction's unit instead, whatever its ID is. (custom units will be "seen" too)
Remark:
I noticed that SkirtSizeX and SkirtSizeZ have not default values, so I added tests in order to avoid annoying errors. (I know, this is a cheap solution but it works)
How to use this :
Put this code in a copy of lua/editor/UnitCountBuildConditions.lua then drop it in the hook folder of your mod
Change the build conditions in all of your templates (there are few only  )
examples taken from lua/AI/AIBuilders/AIEconomicBuilders.lua:
Code: --Now it won't work on 'ueb1106' (only!!), instead it will work with 'MASSSTORAGE' ! { UCBC, 'AdjacencyCheck', { 'LocationType', 'MASSEXTRACTION TECH3', 100, 'MASSSTORAGE' } },
Code: --Now it won't work on 'ueb1105' (only!!), instead it will work with 'ENERGYSTORAGE' ! { UCBC, 'AdjacencyCheck', { 'LocationType', 'ENERGYPRODUCTION TECH3', 100, 'ENERGYSTORAGE' } },
Scripting it:First of all, it needs to know the path to the file named BuildingTemplates:Code: --my little handy function will get the path
GetMyMod = function( byName, byUID, byAuthor ) for i, mod in __active_mods do if (byName and ( byName == mod.name )) or (byUID and ( byUID == mod.uid )) or (byAuthor and ( byAuthor == mod.author )) then LOG("MANIMAL\'s DEBUG: Mod Location = "..mod.location) return mod end end WARN("MANIMAL\'s MOD LOCATOR: Unable to get Mod Infos ! Either your mod is not installed or you have mistyped its name, UID or author.") return {} end
-- UID de SupCivs Beta local MyModInfos = GetMyMod( false, "3415261C-75B7-11DC-A11D-A05155D89593", false ) local MyModDir = MyModInfos.location local MyHookDir = MyModDir..MyModInfos.hookdir
local BuildingTemplates = import( MyHookDir .. '/lua/BuildingTemplates.lua' ).BuildingTemplates Now here is the newly rewrote function:Code: # ======================================================================================= # # Adjacency Check - Ensures a building category can have something adjacent to it # # # # Altered by Manimal - Now works with a building template instead of unit ID ! # # ======================================================================================= #
function AdjacencyCheck( aiBrain, locationType, category, radius, testCatUnit ) local factoryManager = aiBrain.BuilderManagers[locationType].FactoryManager if not factoryManager then WARN('*AI WARNING: FactoryCapCheck - Invalid location - ' .. locationType) return false end
local testCat = category if type(category) == 'string' then testCat = ParseEntityCategory(category) end local reference = AIUtils.GetOwnUnitsAroundPoint( aiBrain, testCat, factoryManager:GetLocationCoords(), radius ) if not reference or table.getn(reference) == 0 then return false end local factionIndex = aiBrain:GetFactionIndex()
## ####################################################################################################### ## Given a faction, get the building unit from BuildingTemplates ! ## #######################################################################################################
local GetBuildingIDfromCategory = function ( factionIndex, category ) if type(category) == 'string' and factionIndex and factionIndex > 0 then for indF, faction in BuildingTemplates do if indF == factionIndex then for i, structUnit in faction do if structUnit[1] and structUnit[1] ~= "" and string.upper(structUnit[1]) == category then --LOG("¤¤¤ MANIMAL\'s DEBUG: UnitCountBuildConditions.lua -> AdjacencyCheck: GetBuildingIDfromCategory VERIFICATION DES DONNÉES :") --LOG("¤¤¤ -----> structUnit[1]="..structUnit[1]) ## e.g. structUnit[1]='MASSEXTRACTION' --LOG("¤¤¤ -----> structUnit[2]="..structUnit[2]) ## e.g. structUnit[2]='MassStorage' return structUnit[2] end end end end end return nil --FAILURE : either Category or structureUnit don't exist end local testUnit = GetBuildingIDfromCategory( factionIndex, testCatUnit ) if not testUnit or testUnit == nil then WARN("¤¤¤ MANIMAL\'s DEBUG: UnitCountBuildConditions.lua -> AdjacencyCheck: GetBuildingIDfromCategory FAILURE => unable to check Adjacency !") return false end
## #######################################################################################################
local template = {} local unitSize = aiBrain:GetUnitBlueprint( testUnit ).Physics if unitSize.SkirtSizeX == nil then WARN("¤¤¤ MANIMAL\'s DEBUG: UnitCountBuildConditions.lua -> AdjacencyCheck: unitSize.SkirtSizeX is NIL ! testUnit="..repr(testUnit) or "HAS NO AVAIBLE INFOS !!!") return false end if unitSize.SkirtSizeZ == nil then WARN("¤¤¤ MANIMAL\'s DEBUG: UnitCountBuildConditions.lua -> AdjacencyCheck: unitSize.SkirtSizeZ is NIL ! testUnit="..repr(testUnit) or "HAS NO AVAIBLE INFOS !!!") return false end for k,v in reference do if not v:IsDead() then local targetSize = v:GetBlueprint().Physics local targetPos = v:GetPosition() local myUnit = v:GetBlueprint() if targetSize.SkirtSizeX == nil then WARN("¤¤¤ MANIMAL\'s DEBUG: UnitCountBuildConditions.lua -> AdjacencyCheck: targetSize.SkirtSizeX is NIL ! unit="..myUnit.General.UnitName or myUnit.Interface.HelpText or myUnit.Interface.Description or "HAS NO AVAIBLE INFOS !!!".." v="..repr(v)) return false end if targetSize.SkirtSizeZ == nil then WARN("¤¤¤ MANIMAL\'s DEBUG: UnitCountBuildConditions.lua -> AdjacencyCheck: targetSize.SkirtSizeZ is NIL ! unit="..myUnit.General.UnitName or myUnit.Interface.HelpText or myUnit.Interface.Description or "HAS NO AVAIBLE INFOS !!!".." v="..repr(v)) return false end targetPos[1] = targetPos[1] - (targetSize.SkirtSizeX/2) targetPos[3] = targetPos[3] - (targetSize.SkirtSizeZ/2) # Top/bottom of unit for i=0,((targetSize.SkirtSizeX/2)-1) do local testPos = { targetPos[1] + 1 + (i * 2), targetPos[3]-(unitSize.SkirtSizeZ/2), 0 } local testPos2 = { targetPos[1] + 1 + (i * 2), targetPos[3]+targetSize.SkirtSizeZ+(unitSize.SkirtSizeZ/2), 0 } table.insert( template, testPos ) table.insert( template, testPos2 ) end # Sides of unit for i=0,((targetSize.SkirtSizeZ/2)-1) do local testPos = { targetPos[1]+targetSize.SkirtSizeX + (unitSize.SkirtSizeX/2), targetPos[3] + 1 + (i * 2), 0 } local testPos2 = { targetPos[1]-(unitSize.SkirtSizeX/2), targetPos[3] + 1 + (i*2), 0 } table.insert( template, testPos ) table.insert( template, testPos2 ) end end end for k,v in template do if aiBrain:CanBuildStructureAt(testUnit, { v[1], 0, v[2] } ) then return true end end return false end
_________________ Console Plus - Solo A.C.U. - Experimental Wars
|
|
| Top |
|
 |
|
furynik
|
Posted: 14 Sep, 2008
|
|
Joined: 09 Feb, 2008 Posts: 44 Location: France
|
[FA] Save & Restore selected construction tabs & command mode
UISelectionByCategory & SelectUnits reset construction context (if one of these function is called while you try to do an upgrade on ACU for exemple, the construction tab is displayed)
construction.lua must be hooked as follow
Code: -- File: hook/lua/ui/game/construction.lua -- Author: FuryNik -- Summary: Add SaveCheckedTab & RestoreCheckedTab -- Version: 0.1 -- Revision -- 0.1 09-09-2008 Creation
local savedTab = false local savedNestedTab = false
function SaveCheckedTab() savedTab = false savedNestedTab = false
if controls.constructionTab._checkState == 'checked' then savedTab = 'construction' end if controls.selectionTab._checkState == 'checked' then savedTab = 'selection' end if controls.enhancementTab._checkState == 'checked' then savedTab = 'enhancement' end if GetTabByID('LCH') and GetTabByID('LCH'):IsChecked() then savedNestedTab = 'LCH' end if GetTabByID('Back') and GetTabByID('Back'):IsChecked() then savedNestedTab = 'Back' end if GetTabByID('RCH') and GetTabByID('RCH'):IsChecked() then savedNestedTab = 'RCH' end if GetTabByID('templates') and GetTabByID('templates'):IsChecked() then savedNestedTab = 'templates' end if GetTabByID('t1') and GetTabByID('t1'):IsChecked() then savedNestedTab = 't1' end if GetTabByID('t2') and GetTabByID('t2'):IsChecked() then savedNestedTab = 't2' end if GetTabByID('t3') and GetTabByID('t3'):IsChecked() then savedNestedTab = 't3' end if GetTabByID('t4') and GetTabByID('t4'):IsChecked() then savedNestedTab = 't4' end end
function RestoreCheckedTab() if not savedTab then return end if savedTab == 'construction' and controls.constructionTab._checkState != 'checked' then controls.constructionTab:ToggleCheck() end if savedTab == 'selection' and controls.selectionTab._checkState != 'checked' then controls.selectionTab:ToggleCheck() end if savedTab == 'enhancement' and controls.enhancementTab._checkState != 'checked' then controls.enhancementTab:ToggleCheck() end lastCheckedTab = savedTab savedTab = false if savedNestedTab then GetTabByID(savedNestedTab):SetCheck(true) end end Usage example : Code: import('/lua/ui/game/construction.lua').SaveCheckedTab() local selectedUnits = GetSelectedUnits() local commandmode = import('/lua/ui/game/commandmode.lua') local currentCommand = commandmode.GetCommandMode()
UISelectionByCategory("ALLUNITS", false, false, false, false) for _, unit in (GetSelectedUnits() or {}) do unitsList[unit:GetEntityId()] = unit end SelectUnits(selectedUnits) import('/lua/ui/game/construction.lua').RestoreCheckedTab() commandmode.StartCommandMode(currentCommand[1], currentCommand[2])
Hope this helps
|
|
| Top |
|
 |
|
Pawz
|
Posted: 27 Sep, 2008
|
|
Joined: 15 Feb, 2007 Posts: 599 Location: Rockingham, Australia
|
Found this while browsing through some older threads - could be handy
Railgun Weapon (Passes through multiple units) script
Quote: Projectile-script: Code: OnImpactDestroy = function( self, targetType, targetEntity )
if targetEntity and not IsUnit(targetEntity) then NRailgunProjectilePolytrail.OnImpactDestroy(self, targetType, targetEntity) return end if self.counter then if self.counter >= 3 then NRailgunProjectilePolytrail.OnImpactDestroy(self, targetType, targetEntity) return else self.counter = self.counter + 1 end else self.counter = 1 end if targetEntity then self.lastimpact = targetEntity:GetEntityId() #remember what was hit last end end, }
addet text in unit.lua : Code: Code: local oldUnit=Unit Unit = Class(oldUnit) { OnCollisionCheck = function(self, other, firingWeapon) if other.lastimpact and other.lastimpact == self:GetEntityId() then return false end return oldUnit.OnCollisionCheck(self, other, firingWeapon) end, }
_________________ We are Supremilated
www.supremilated.com
|
|
| Top |
|
 |
|
Neruz
|
Posted: 24 Nov, 2008
|
|
Joined: 28 Feb, 2007 Posts: 918
|
I'm gonna post several scripts, and I rather not put each in a seperate post.
Using methods on strings :
Comment the line metacleanup('') in mohodata/lua/system/config.lua.
Now you can do things like :
Code: local s = '' local slen = s:len()
or
local slen = (''):len() # '':len() is invalid syntax
I find it a lot easier than typing string.len(s). Ignore errors when accessing nil values :Open mohodata/lua/system/config.lua, and look for the globalsmeta table around line ~50. Comment the line that calls error(). Accessing nil values no longer cause scripts to halt. This helps a lot, sometimes I need to check for a value, and it's not 100% that its set yet, and it would halt the script normally. Quite stupid imho. Replacing error with WARN is good too. Lua only classes:This is an implementation to support Destroy() on lua-only classes. Your new class should only override OnCreate() and OnDestroy() . Code: --[[ Support for LUA-only objects. --]] local oldIsDestroyed = IsDestroyed function IsDestroyed(obj) return obj.__IsDestroyed or oldIsDestroyed(obj) end
--[[ This is a base class for LUA-only classes to support Destroy
(). OnCreate and OnDestroy should be overloaded. Includes ForkThread. --]] LuaClass = Class { __init = function(self, spec) self._trash = TrashBag() self:OnCreate(spec) end, ForkThread = function(self, fn, ...) if fn then local thread = ForkThread(fn, self, unpack(arg)) self._trash:Add(thread) return thread else return nil end end, --[[ Override the object's metatable, when index is accessed, it'll
return nil and LOG a WARN. --]] Destroy = function(self) self:OnDestroy() local destroyedFrom = debug.traceback('Object has been
destroyed from:') local oldMeta = getmetatable(self) metatable = { __index = function(self, key) local _type = type(rawget(oldMeta,
key)) WARN('Tried to access key: [' .. key
.. ' = ' .. _type .. '] but object was destroyed\n' .. destroyedFrom) return nil end, } setmetatable(self, metatable) self.__IsDestroyed = true self._trash:Destroy() end, OnCreate = function(self, spec) end, OnDestroy = function(self) end, }
Removing the annoying \000 in logs:Code: # removes the \000 when passing multiple arguments, arguments are
concatenated with ' '
local oldLOG = LOG function LOG(...) local joined = (' '):join(arg) oldLOG(joined) end
local oldWARN = WARN function WARN(...) local joined = (' '):join(arg) oldWARN(joined) end
local oldSPEW = SPEW function SPEW(...) local joined = (' '):join(arg) oldSPEW(joined) end
local oldError = error function error(...) local joined = (' '):join(arg) oldError(joined) end
# same as python's ''.join(list) function string.join(str, tbl) local s = '' # sometimes the arg from LOGs are 'dirty' and the 'real' values can be unpacked with unpack local args = {unpack(tbl)} for k, arg in args do s = s .. tostring(arg) .. str end return s end
Convert a quaternion to euler roll, pitch, yaw Code: # # Convert a quaternion value to euler degrees. # function QuaternionToEuler(quaternion) local qx, qy, qz, qw = unpack(quaternion) local ys = (2*qy*qw) - (2*qx*qz) local yc = 1 - (2 * math.pow(qy, 2)) - (2 * math.pow(qz, 2)) local yaw = math.atan2(ys, yc) local pitch = math.asin(2*qx*qy + 2*qz*qw) local rs = (2*qx*qw ) - (2*qy*qz) local rc = 1 - (2 * math.pow(qx, 2)) - (2 * math.pow(qz, 2)) local roll = math.atan2(rs, rc) return pitch, roll, yaw end
Get camera position in the world: Code: --[[ Get the camera position in the game world. returns x, y, z --]] function GetCameraWorldPos(camera) if not camera then camera = GetCamera('WorldCamera') end local cSettings = camera:SaveSettings() local x, y, z = unpack(cSettings.Focus) local heading = cSettings.Heading local pitch = cSettings.Pitch local zoom = cSettings.Zoom local height = math.sin(pitch) * zoom local base = math.cos(pitch) * zoom return x + (math.cos(heading) * base), y+height, z + (math.sin(heading) * base) end
|
|
| Top |
|
 |
|
Manimal
|
Posted: 31 Jan, 2009
|
|
Joined: 11 Apr, 2007 Posts: 1915
|
Mod Locator (better explained)I noticed that you're naming explicitly the path to your mod. Here is my little handy script that is subject to enhancements in a close future : In case you need to get "dynamicaly" the path where your mod is currently installed in : Make a copy of /hook/lua/game.lua and add the following portion at its "top" part, below commented out file descriptor Code: local myMod_UID = "123456787-1234-1234-1234-0123456789ab" --UID of The Mod WARNING : CASE SENSITIVE
--[[################################################################################ # Manimal's Mod Locator script # # The functionMyActiveModLocation = function( byName, byUID, byAuthor ) will # # avoid making a list of units which is not convenient to be kept updated each # # time someone creates and add a new unit in his mod. # # This function will require the current Mod's UID ONLY in order to get the # # current active mod's location, that's more convenient as it won't change. # # It could work also by mod NAME or AUTHOR name. # ################################################################################]]--
local GetMyActiveMod = function( byName, byUID, byAuthor ) for i, leMod in __active_mods do if (byName and ( byName == leMod.name )) or (byUID and ( byUID == leMod.uid )) or (byAuthor and ( byAuthor == leMod.author )) then --LOG("MANIMAL\'s DEBUG: Mod infos = "..repr(leMod)) return leMod end end WARN("MANIMAL\'s MOD FINDER: Unable to get Mod Infos ! Either your mod is not installed or you have mistyped its name, UID or author.") return {} end
local GetMyActiveModLocation = function( leMod ) if leMod and (type(leMod) == 'table') then --LOG("MANIMAL\'s DEBUG: Mod Location = " .. leMod.location) return leMod.location end WARN("MANIMAL\'s MOD LOCATOR: Unable to get Mod Infos ! Either your mod is not installed or you have mistyped its name, UID or author.") return "" end
# GET and STORE the PATH for Later Access :D MonMod = GetMyActiveMod( false, myMod_UID, false ) MyModPath = GetMyActiveModLocation( MonMod )
Then insert the following portion in any LUA that needs it : Code: local Game = import('/lua/game.lua') local MyModPath = Game.MyModPath example of an altered version of uiutils.lua that will allow your own strategic icons to show up (among others): Code: function UIFile(filespec) --local skins = import('/lua/skins/skins.lua').skins local visitingSkin = currentSkin() local currentPath = skins[visitingSkin].texturesPath
if visitingSkin == nil or currentPath == nil then return nil end # ================================= # TRAITER LES SKINS ORIGINAUX EN PREMIER. # Traiter les skins du Mod ensuite. # ====================================== if visitingSkin == 'default' then -- if current skin is default, then don't bother trying to look for it, just append the default dir local curFile = currentPath .. filespec if DiskGetFileInfo(curFile) then return curFile else curFile = MyModPath .. curFile if DiskGetFileInfo(curFile) then return curFile end end else while visitingSkin do local curFile = currentPath .. filespec if DiskGetFileInfo(curFile) then return curFile else curFile = MyModPath .. curFile if DiskGetFileInfo(curFile) then return curFile else visitingSkin = skins[visitingSkin].default if visitingSkin then currentPath = skins[visitingSkin].texturesPath end end end end end
WARN('Warning: uiutil.lua -> UIFile: Unable to find file ', filespec) -- pass out the final string anyway so resource loader can gracefully fail return filespec end Quiet simple and functional !  Note that the UID is fictive in this example, you need your own UIDSee /mohodata/lua/mods.lua for more informations. Please keep the credits as is and eventually keep me informed of any significant changes / enhancements you brought to my script.
_________________ Console Plus - Solo A.C.U. - Experimental Wars
Last edited by Manimal on 23 May, 2010, edited 2 times in total.
|
|
| Top |
|
 |
|
Ghaleon
|
Posted: 31 Jan, 2009
|
|
Joined: 13 Jun, 2008 Posts: 729
|
The table below will allow to recreate the in-game map info dialog.
SessionGetScenarioInfo() will return the table.
furynik wrote: Code: SessionGetScenarioInfo = { Configurations={ standard={ customprops={ ExtraArmies="ARMY_9 NEUTRAL_CIVILIAN" }, teams={ { armies={ "ARMY_1", "ARMY_2" }, name="FFA" } } } }, Options={ AllowObservers=true, CheatsEnabled="false", CivilianAlliance="enemy", FogOfWar="explored", GameSpeed="normal", NoRushOption="Off", PrebuiltUnits="Off", ScenarioFile="/maps/x1mp_002/x1mp_002_scenario.lua", TeamLock="unlocked", TeamSpawn="fixed", Timeouts="3", UnitCap="500", Victory="sandbox" }, description="<LOC X1MP_002_Description>In the waning days of the Earth Empire, this was the location where Commander Williamson valiantly stood his ground against the first Aeon invasion. Recent events have transformed Commander Williamson and the Bridge he once defended into symbols of hope and valor for the UEF people.", map="/maps/X1MP_002/X1MP_002.scmap", name="Williamson's Bridge", norushoffsetX_ARMY_1=0, norushoffsetX_ARMY_2=0, norushoffsetY_ARMY_1=0, norushoffsetY_ARMY_2=0, norushradius=75, preview="", save="/maps/X1MP_002/X1MP_002_save.lua", script="/maps/X1MP_002/X1MP_002_script.lua", size={ 256, 256 }, starts=true, type="skirmish" }
_________________ TVg V5 Alpha Testers Wanted!
 Bulletstorm released other mods
|
|
| Top |
|
 |
|
Ghaleon
|
Posted: 31 Jan, 2009
|
|
Joined: 13 Jun, 2008 Posts: 729
|
furynik wrote: Well, the ARMY_x match the start pos on the map and this is a code to get the list of all units without selecting units : /mods/<modname>/hook/lua/ui/game/scoreaccum.lua Code: -- File: scoreaccum.lua local original_UpdateScoreData = UpdateScoreData
function UpdateScoreData(newData) original_UpdateScoreData(newData) import('/mods/<modname>/lib/score.lua').UpdateScoreData(newData) end /mods/<modname>/lib/score.lua Code: -- File: score.lua local scoreData = {}
function UpdateScoreData(newData) scoreData = table.deepcopy(newData) end
function GetScoreData() return scoreData end /mods/<modname>/lib/units.lua Code: -- File: units.lua local GetScoreData = import('/mods/<modname>/lib/score.lua').GetScoreData
-- return the table of all existing units function GetAllUnits() local unitsList = {} local newCount = 0 local unit = nil local id = 0 -- get unit count in the score data local curCount = GetScoreData()[GetFocusArmy()].general.currentunits.count
-- loop until unit count reached while newCount < curCount do unit = GetUnitById(id) if unit != nil then unitsList[newCount] = unit newCount = newCount + 1 end id = id + 1 end -- LOG('Units management: units list: ', repr(unitsList)) return unitsList end
_________________ TVg V5 Alpha Testers Wanted!
 Bulletstorm released other mods
|
|
| Top |
|
 |
|
Resin_Smoker
|
Posted: 01 Apr, 2009
|
|
Joined: 01 May, 2007 Posts: 4219
|
Carrier and Drone Scripts...
Resin_Smoker
Carrier Script
Code: #**************************************************************************** #** #** File : URA0305_script.lua #** Author : Resin_Smoker, Optimus Prime #** #** Summary : Cybran Retribution, Airborne Drone Carrier #** #** Special Thanks to : ChirmayaWrongEmail, Eni, Neruz, Goom, Gilbot-X #** #** Copyright © 2009, 4th Dimension #****************************************************************************
#### Localy imported files #### local CAirUnit = import('/lua/cybranunits.lua').CAirUnit
#### Weapon local files #### local CollisionBeamFile = import('/mods/4th_Dimension_201/hook/lua/ura0305_defaultcollisionbeams.lua') local DefaultBeamWeapon = import('/lua/sim/defaultweapons.lua').DefaultBeamWeapon LaserBeamWeapon = Class(DefaultBeamWeapon) { BeamType = CollisionBeamFile.RetributionGreenLaserCollisionBeam, FxMuzzleFlash = {}, } local CDFProtonCannonWeapon = import('/lua/cybranweapons.lua').CDFProtonCannonWeapon local CAAMissileNaniteWeapon = import('/lua/cybranweapons.lua').CAAMissileNaniteWeapon
URA0305 = Class(CAirUnit) {
Weapons = { TriCannon = Class(CDFProtonCannonWeapon) {}, GreenLaser = Class(LaserBeamWeapon) {}, AA_Front_L = Class(CAAMissileNaniteWeapon) {}, AA_Front_R = Class(CAAMissileNaniteWeapon) {}, AA_Rear_L = Class(CAAMissileNaniteWeapon) {}, AA_Rear_R = Class(CAAMissileNaniteWeapon) {}, },
ExhaustBones = { 'engine_center01','engine_center02','engine_center03','engine_center04','engine_center05','engine_center06', 'engine_left01','engine_left02','engine_left03','engine_left04','engine_left05','engine_left06', 'engine_right01','engine_right02','engine_right03','engine_right04','engine_right05','engine_right06', },
BeamExhaustCruise = '/effects/emitters/gunship_thruster_beam_01_emit.bp', BeamExhaustIdle = '/effects/emitters/gunship_thruster_beam_01_emit.bp',
OnStopBeingBuilt = function(self,builder,layer) CAirUnit.OnStopBeingBuilt(self,builder,layer) ### Initializes Drone spawn sequence and radar jammer energy useage self:ForkThread(self.InitialDroneSpawn) self:SetMaintenanceConsumptionInactive() self:SetScriptBit('RULEUTC_StealthToggle', true) self:SetScriptBit('RULEUTC_ProductionToggle', false) self:RequestRefreshUI() self.UnitComplete = true self.Army = self:GetArmy()
### Drone Globals self.Side = 0 self.DroneTable = {}
### Globals uses for target assists and counter attacks self.CurrentTarget = nil self.OldTarget = nil self.MyAttacker = nil self.Retaliation = false end,
OnIntelEnabled = function(self) CAirUnit.OnIntelEnabled(self) ### Radar rotation on jammer activation if not self:IsDead() and not self.SpinManip then self.SpinManip = CreateRotator(self, 'radar_dish', 'y', nil, 0, 20, 100) self.Trash:Add(self.SpinManip) end if not self:IsDead() and self.SpinManip then self.SpinManip:SetTargetSpeed(100) end end,
OnIntelDisabled = function(self) CAirUnit.OnIntelDisabled(self) ### Radar rotation halt on jammer de-activation if not self:IsDead() and self.SpinManip then self.SpinManip:SetTargetSpeed(0) end end,
InitialDroneSpawn = function(self) ### spawning a number of drones times equal to the number preset by numcreate local numcreate = 8 ### Randomly determines which launch bay will be the first to spawn a drone self.Side = Random(1,2) ### Short delay after the carrier has been built WaitSeconds(2) ### Are we dead yet, if not spawn drones if not self:IsDead() then for i = 0, (numcreate -1) do if not self:IsDead() then self:ForkThread(self.SpawnDrone) ### Short delay between spawns to spread them out WaitSeconds(1) end end ### Runs assist commands only after all of the drones have been built self:AssistHeartBeat() end end,
SpawnDrone = function(self) ### Small respawn delay so the drones are not instantly respawned after death WaitSeconds(1) ### Only respawns the drones if the parent unit is not dead if not self:IsDead() then ### Sets up local Variables used and spawns a drone at the parents location local myOrientation = self:GetOrientation() if self.Side == 1 then ### Gets the current position of the carrier launch bay in the game world local location = self:GetPosition('drone_launch_left') ### Creates our drone in the left launch bay and directs the unit to face the same direction as its parent unit local drone = CreateUnit('ura0106', self:GetArmy(), location[1], location[2], location[3], myOrientation[1], myOrientation[2], myOrientation[3], myOrientation[4], 'Air') ### Adds the newly created drone to the parent carriers drone table table.insert (self.DroneTable, drone) ### Sets the Carrier unit as the drones parent drone:SetParent(self, 'ura0305') drone:SetCreator(self) ### Issues the move command IssueClearCommands({drone}) local destination = self:CalculateWorldPositionFromRelative({-5,0,30}) IssueMove({drone}, destination) ### Flips from the left to the right self.Side after a drone has been spawned self.Side = 2 ###Drone clean up scripts self.Trash:Add(drone) elseif self.Side == 2 then ### Gets the current position of the carrier launch bay in the game world local location = self:GetPosition('drone_launch_right') ### Creates our drone in the right launch bay and directs the unit to face the same direction as its parent unit local drone = CreateUnit('ura0106', self:GetArmy(), location[1], location[2], location[3], myOrientation[1], myOrientation[2], myOrientation[3], myOrientation[4], 'Air') ### Adds the newly created drone to the parent carriers drone table table.insert (self.DroneTable, drone) ### Sets the Carrier unit as the drones parent drone:SetParent(self, 'ura0305') drone:SetCreator(self) ### Issues the move command IssueClearCommands({drone}) local destination = self:CalculateWorldPositionFromRelative({5, 0, 30}) IssueMove({drone}, destination) ### Flips from the right to the left self.Side after a drone has been spawned self.Side = 1 ###Drone clean up scripts self.Trash:Add(drone) end end end,
NotifyOfDroneDeath = function(self) ### Only respawns the drones if the parent unit is not dead if not self:IsDead() then local mass = self:GetAIBrain():GetEconomyStored('Mass') local energy = self:GetAIBrain():GetEconomyStored('Energy') ### Check to see if the player has enough mass / energy ### And that the production is enabled. if self:GetScriptBit('RULEUTC_ProductionToggle') == false and mass >= 100 and energy >= 1000 then ###Remove the resources and spawn a single drone self:GetAIBrain():TakeResource('Mass',100) self:GetAIBrain():TakeResource('Energy',1000) self:ForkThread(self.SpawnDrone) else ### If the above conditions are not met the carrier will wait a short time and try again self:ForkThread(self.EconomyWait) end end end,
EconomyWait = function(self) if not self:IsDead() then WaitSeconds(5) if not self:IsDead() then self:ForkThread(self.NotifyOfDroneDeath) end end end,
AssistHeartBeat = function(self) while not self:IsDead() do WaitSeconds(1) if not self:IsDead() and self.Retaliation == true and self.MyAttacker != nil then ### Clears flags if there is no longer a target to retaliate against thats in range if self.MyAttacker:IsDead() or self:GetDistanceToAttacker() >= 31 then ### Clears flag to allow retaliation on another attacker self.MyAttacker = nil self.Retaliation = false end end if not self:IsDead() and self.Retaliation == false and table.getn({self.MyAttacker}) > 0 and self:GetDistanceToAttacker() <= 30 then if not self.MyAttacker:IsDead() then ###Issues the retaliation command to each of the drones on the carriers table if table.getn({self.DroneTable}) > 0 then for k, v in self.DroneTable do IssueClearCommands({self.DroneTable[k]}) IssueAttack({self.DroneTable[k]}, self.MyAttacker) end ### Performs retaliation flag self.Retaliation = true end end elseif not self:IsDead() and self.Retaliation == false and self:GetTargetEntity() then ### Updates variable with latest targeting info self.CurrentTarget = self:GetTargetEntity() ### Verifies that the carrier is not dead and that it has a target ### Ensures that either there hasnt been a target before or that its new ### To prevent the same retargeting command from being given out multible times if self.OldTarget == nil or self.OldTarget != self.CurrentTarget then ### Updates the OldTarget to match CurrentTarget self.OldTarget = self.CurrentTarget ###Issues the attack command to each of the drones on the carriers table if table.getn({self.DroneTable}) > 0 then for k, v in self.DroneTable do IssueClearCommands({self.DroneTable[k]}) IssueAttack({self.DroneTable[k]}, self.CurrentTarget) end end end end end end,
GetDistanceToAttacker = function(self) local tpos = self.MyAttacker:GetPosition() local mpos = self:GetPosition() local dist = VDist2(mpos[1], mpos[3], tpos[1], tpos[3]) return dist end,
OnDamage = function(self, instigator, amount, vector, damagetype) ### Check to make sure that the carrier isnt already dead and what just damaged it is a unit we can attack if self:IsDead() == false and damagetype == 'Normal' and self.MyAttacker == nil then ### only attack if retaliation not already active if IsUnit(instigator) then self.MyAttacker = instigator end end CAirUnit.OnDamage(self, instigator, amount, vector, damagetype) end,
OnKilled = function(self, instigator, type, overkillRatio) ### Disables the laser beam after death local wep = self:GetWeaponByLabel('GreenLaser') for k, v in wep.Beams do v.Beam:Disable() end if self.BeamFX then self.BeamFX:Destroy() end ### Disables weapons after death self:SetWeaponEnabledByLabel('GreenLaser', false) self:SetWeaponEnabledByLabel('FrontCannon', false) self:SetWeaponEnabledByLabel('AA_Front_L', false) self:SetWeaponEnabledByLabel('AA_Front_R', false) self:SetWeaponEnabledByLabel('AA_Rear_L', false) self:SetWeaponEnabledByLabel('AA_Rear_R', false) ### Small bit of table manipulation to sort thru all of the avalible drones and remove them after the carrier is dead if table.getn({self.DroneTable}) > 0 then for k, v in self.DroneTable do IssueClearCommands({self.DroneTable[k]}) IssueKillSelf({self.DroneTable[k]}) end end ### Removes radar spin effects if self.SpinManip then self.Trash:Add(self.SpinManip) end ### Final command to finish off the carriers death event CAirUnit.OnKilled(self, instigator, type, overkillRatio) end, } TypeClass = URA0305
Drone ScriptCode: #**************************************************************************** #** #** File : URA0106_script.lua #** Author(s): Resin_Smoker, Optimus Prime #** #** Summary : Cybran Mosquito, Drone Gunship Script #** #** Special Thanks to : ChirmayaWrongEmail, Eni, Neruz, Goom, Gilbot-X, Sorian #** #** Copyright © 2009 #****************************************************************************
#### Localy imported files #### local CAirUnit = import('/lua/cybranunits.lua').CAirUnit local EffectUtil = import('/lua/EffectUtilities.lua') local util = import('/lua/utilities.lua')
#### Weapon local files #### local CAAAutocannon = import('/lua/cybranweapons.lua').CAAAutocannon
URA0106 = Class(CAirUnit) { Weapons = { MainGun = Class(CAAAutocannon) { CreateProjectileAtMuzzle = function(self, muzzle) if not self.unit:IsDead() and self.unit:GetWeaponByLabel('MainGun'):GetCurrentTarget() then local myWeapon = self.unit:GetWeaponByLabel('MainGun') local myTarget = myWeapon:GetCurrentTarget() ### Checks current target for its unit category and sets the weapons stats accordingly if table.find(myTarget:GetBlueprint().Categories,'AIR') and not table.find(myTarget:GetBlueprint().Categories,'EXPERIMENTAL') then ### Prevents the Activation of the DMG modification if it is already on if self.unit.DmgMod == false then myWeapon:SetFiringRandomness(myWeapon:GetBlueprint().FiringRandomness) myWeapon:AddDamageMod(-20) self.unit.DmgMod = true end elseif self.unit.DmgMod == true then ### Prevents the De-activation of the DMG modification if it is already off myWeapon:SetFiringRandomness(myWeapon:GetBlueprint().FiringRandomness * 2) myWeapon:AddDamageMod(20) self.unit.DmgMod = false end end local proj = CAAAutocannon.CreateProjectileAtMuzzle(self, muzzle) end, }, }, ### File pathing and special paramiters called ###########################
### Setsup parent call backs between drone and parent Parent = nil,
SetParent = function(self, parent, droneName) self.Parent = parent self.Drone = droneName end,
### Afterburner and exhaust effect pathing
BeamAfterBurner = '/effects/emitters/aeon_nuke_exhaust_beam_01_emit.bp', BeamCruise = '/effects/emitters/aeon_nuke_exhaust_beam_02_emit.bp', ExhaustSmoke = '/effects/emitters/missile_smoke_exhaust_02_emit.bp', ##########################################################################
OnCreate = function(self, builder, layer) CAirUnit. OnCreate(self,builder,layer) if not self:IsDead() then ### Disables weapons self:SetWeaponEnabledByLabel('MainGun', false) self:SetScriptBit('RULEUCC_RetaliateToggle', false) ### Global Varibles self.BeamExhaustEffectsBag = {} self.BurnerActive = false self.Evade = false self.MoveToParent = false self.Duration = 1 self.MyWeapon = self:GetWeaponByLabel('MainGun') self.MyMaxSpeed = self:GetBlueprint().Air.MaxAirspeed self.WepRng = self.MyWeapon:GetBlueprint().MaxRadius self.DmgMod = false ### Start of launch special effects self:ForkThread(self.LaunchEffects) end end,
LaunchEffects = function(self) ### Are we dead? if not self:IsDead() then ### Set flag to true self.BurnerActive = true ### Kick off Afterburner multi and effects self:ForkThread(self.Afterburner) ### Duration of launch WaitSeconds(self.Duration) if not self:IsDead() and not self.Parent:IsDead() then ### Tells the drone to guard the carrier self:ForkThread(self.GuardCarrier) ### Enables weapons self:SetWeaponEnabledByLabel('MainGun', true) self:SetScriptBit('RULEUCC_RetaliateToggle', true) ### Heartbeat event to monitor the drones distance from the carrier, if the drone gets too far away it is recalled to the carrier self:HeartBeatDroneCheck() end end end, HeartBeatDroneCheck = function(self) while self and not self:IsDead() do ### Verify that we have fuel and get distance from parent carrier local myFuel = self:GetFuelRatio() local dronePos = self:GetPosition() local parentPos = self.Parent:CalculateWorldPositionFromRelative({0, 0, 25}) local parentDist = VDist2(dronePos[1], dronePos[3], parentPos[1], parentPos[3]) if myFuel <= 0 then ### Kill drone if no fuel avalible self:Kill(self,'Normal',0) elseif parentDist >= 70 and self.Evade == false and self.MoveToParent == false then ### Set flag to true self.MoveToParent = true ### Disables weapons and attempts to move drone back to parent self:SetWeaponEnabledByLabel('MainGun', false) self:SetScriptBit('RULEUCC_RetaliateToggle', false) IssueClearCommands({self}) IssueMove({self}, parentPos) elseif parentDist <= 70 then ### Set flag to false self.MoveToParent = false ### Enables weapons self:SetWeaponEnabledByLabel('MainGun', true) self:SetScriptBit('RULEUCC_RetaliateToggle', true) if self.MyWeapon:GetCurrentTarget() then local myTarget = self.MyWeapon:GetCurrentTarget() ### Verify that our current target is a valid air target if table.find(myTarget:GetBlueprint().Categories,'HIGHALTAIR') and not table.find(myTarget:GetBlueprint().Categories,'EXPERIMENTAL') then ### Get the distance to our target local tarPos = myTarget:GetPosition() local distance = VDist2(dronePos[1], dronePos[3], tarPos[1], tarPos[3]) local myTargetSpeed = myTarget:GetBlueprint().Air.MaxAirspeed ### Sets the fighter max speed to that of the target to help prevent overshoot. if distance <= self.WepRng and self.Evade == false then ### Compute the speed of the target and match it self:SetSpeedMult(myTargetSpeed / self.MyMaxSpeed) self:SetAccMult(1.0) self:SetTurnMult(1.5) ### If our target is out of weapons range then engage afterburner elseif distance > self.WepRng and self.BurnerActive == false then ### Set flag to true self.BurnerActive = true ### Kick off Afterburner multi and effects self:ForkThread(self.Afterburner) end end else ### Tells the drone to guard the carrier self:ForkThread(self.GuardCarrier) end end ### Delay between checks WaitSeconds(0.25) end end, OnMotionHorzEventChange = function(self, new, old) ### Should the drone stop flying it will automaticly be re-assigned to guard the carrier if not self:IsDead() and new == 'Stopped' and not self.Parent:IsDead() then ### Clears the current drone commands if any and forces the drone to guard the carrier self:ForkThread(self.GuardCarrier) elseif not self:IsDead() and new == 'Stopping' and not self.Parent:IsDead() then ### Clears the current drone commands if any and forces the drone to guard the carrier self:ForkThread(self.GuardCarrier) end CAirUnit.OnMotionHorzEventChange(self, new, old) end, GuardCarrier = function(self) if not self:IsDead() and not self.Parent:IsDead() then ### Tells the drone to guard the carrier IssueClearCommands(self) IssueGuard({self}, self.Parent) end end, OnDamage = function(self, instigator, amount, vector, damagetype) CAirUnit.OnDamage(self, instigator, amount, vector, damagetype) if self:IsDead() == false and instigator and IsUnit(instigator) then local myFuel = self:GetFuelRatio() if self.BurnerActive == false and myFuel > 0 then ### Set flags to true self.BurnerActive = true self.Evade = true ### Kick off Afterburner multi and effects self:ForkThread(self.Afterburner) end end end,
Afterburner = function(self) if not self:IsDead() then if self.BeamExhaustEffectsBag then ### Engine effects clean up EffectUtil.CleanupEffectBag(self,'BeamExhaustEffectsBag') end ### Engage Afterburn speed and turn rates self:SetSpeedMult(1.5) self:SetAccMult(2.0) self:SetTurnMult(0.5) ### Afterburner sound effects self:PlayUnitSound('Launch') ### Afterburn effects and smoke table.insert(self.BeamExhaustEffectsBag, CreateAttachedEmitter(self, 'contrail', self:GetArmy(), self.ExhaustSmoke):ScaleEmitter(0.25)) table.insert(self.BeamExhaustEffectsBag, CreateBeamEmitterOnEntity(self, 'exhaust', self:GetArmy(), self.BeamAfterBurner):ScaleEmitter(0.2)) ### Play Afterburner sound effects self:PlayUnitSound('Afterburn') ### Get current fuel levels local preBurnFuel = self:GetFuelRatio() ### Duration of Afterburn WaitSeconds(self.Duration) ### Get the fuel levels post Afterburner local postBurnFuel = self:GetFuelRatio()
### Fuel calculations and Afterburn effect clean up if not self:IsDead() then ### Calculate new fuel levels as per *** BIGOs New ASF MOD *** local newFuelLvl = preBurnFuel - (5 *(preBurnFuel - postBurnFuel)) if newFuelLvl > 0 then self:SetFuelRatio(newFuelLvl) end if self.BeamExhaustEffectsBag then ### Engine effects clean up EffectUtil.CleanupEffectBag(self,'BeamExhaustEffectsBag') end ### Sets cruise thrust effect post afterburn table.insert(self.BeamExhaustEffectsBag, CreateBeamEmitterOnEntity( self, 'engine01', self:GetArmy(), self.BeamCruise):ScaleEmitter(0.1)) table.insert(self.BeamExhaustEffectsBag, CreateBeamEmitterOnEntity( self, 'engine02', self:GetArmy(), self.BeamCruise):ScaleEmitter(0.1)) table.insert(self.BeamExhaustEffectsBag, CreateBeamEmitterOnEntity( self, 'engine03', self:GetArmy(), self.BeamCruise):ScaleEmitter(0.1))
### Resets the speed and turn rates self:SetSpeedMult(1.0) self:SetAccMult(1.0) self:SetTurnMult(1.0) ### Short cool down between Afterburns WaitSeconds(self.Duration) ### Resets Afterburn and Evade triggers if not self:IsDead() then self.BurnerActive = false self.Evade = false end end end end, OnKilled = function(self, instigator, type, overkillRatio) ### Disables weapons self:SetWeaponEnabledByLabel('MainGun', false)
if self.BeamExhaustEffectsBag then ### Engine effects clean up EffectUtil.CleanupEffectBag(self,'BeamExhaustEffectsBag') end
### Clears the current drone commands if any IssueClearCommands(self)
### Notifies parent of drone death and clears the offending drone from the parents table if not self.Parent:IsDead() then self.Parent:NotifyOfDroneDeath(self.Drone) table.removeByValue(self.Parent.DroneTable, self) self.Parent = nil end ### Final command to finish off the fighters death event CAirUnit.OnKilled(self, instigator, type, overkillRatio) end, } TypeClass = URA0106
_________________
 Blackhole http://www.youtube.com/watch?v=B3aDT0Ft_Yg WOFhttp://www.youtube.com/watch?v=FVqMqz8PgEc FOD http://www.youtube.com/watch?v=be9cu9UHv-U TML http://www.youtube.com/watch?v=1Apk08LAtxc
Last edited by Resin_Smoker on 13 Apr, 2009, edited 1 time in total.
|
|
| Top |
|
 |
|
Resin_Smoker
|
Posted: 07 Apr, 2009
|
|
Joined: 01 May, 2007 Posts: 4219
|
Afterburner scripts with fuel modification...
Code: #**************************************************************************** #** #** File : UEA0206_script.lua #** Author(s): Resin_Smoker / Vissroid #** #** Summary : UEF Thrasher Script #** #** Copyright © 2009 4th Dimension #****************************************************************************
#### Localy imported files #### local TAirUnit = import('/lua/terranunits.lua').TAirUnit local EffectUtil = import('/lua/EffectUtilities.lua')
#### Weapon local files #### local TAirToAirLinkedRailgun = import('/lua/terranweapons.lua').TAirToAirLinkedRailgun local ZealotMissileWeapon = import('/lua/aeonweapons.lua').AAAZealot02MissileWeapon
UEA0206 = Class(TAirUnit) { Weapons = { MachineGun = Class(TAirToAirLinkedRailgun) {}, Missile_L = Class(ZealotMissileWeapon) {}, Missile_R = Class(ZealotMissileWeapon) {}, },
### File pathing and special paramiters called ###########################
### Afterburner and exhaust effect pathing
BeamAfterBurner = '/effects/emitters/missile_exhaust_fire_beam_01_emit.bp', ExhaustSmoke = '/effects/emitters/missile_smoke_exhaust_02_emit.bp', ##########################################################################
OnStopBeingBuilt = function(self,builder,layer) TAirUnit.OnStopBeingBuilt(self,builder,layer) if not self:IsDead() then ### Global Varibles self.BeamExhaustEffectsBag = {} self.BurnerActive = false self.Evade = false self.MyWeapon = self:GetWeaponByLabel('MachineGun') self.MyMaxSpeed = self:GetBlueprint().Air.MaxAirspeed self.WepRng = self.MyWeapon:GetBlueprint().MaxRadius ### Start of heartbeat event self:ForkThread(self.HeartBeatDistanceCheck) end end, HeartBeatDistanceCheck = function(self) while self and not self:IsDead() do local myFuel = self:GetFuelRatio() ### Make sure we have a target and we have fuel if self.MyWeapon:GetCurrentTarget() and myFuel > 0 then local myTarget = self.MyWeapon:GetCurrentTarget() ### Verify that our current target is a valid air target if table.find(myTarget:GetBlueprint().Categories,'HIGHALTAIR') and not table.find(myTarget:GetBlueprint().Categories,'EXPERIMENTAL') then ### Get the distance to our target local myPos = self:GetPosition() local tarPos = myTarget:GetPosition() local distance = VDist2(myPos[1], myPos[3], tarPos[1], tarPos[3]) local myTargetSpeed = myTarget:GetBlueprint().Air.MaxAirspeed
### Sets the fighter max speed to that of the target to help prevent overshoot. if distance <= self.WepRng and self.Evade == false then LOG('attempting to match speed') ### Engine effects clean up if self.BeamExhaustEffectsBag then EffectUtil.CleanupEffectBag(self,'BeamExhaustEffectsBag') end ### Compute the speed of the target and match it self:SetSpeedMult(myTargetSpeed / self.MyMaxSpeed) self:SetAccMult(1.0) self:SetTurnMult(1.5) ### If our target is out of weapons range then engage afterburner elseif distance > self.WepRng and self.BurnerActive == false then LOG('target is too far away') ### Set flag to true self.BurnerActive = true ### Kick off Afterburner multi and effects self:ForkThread(self.Afterburner) end end end ### Delay between checks WaitSeconds(0.25) end end, OnDamage = function(self, instigator, amount, vector, damagetype) TAirUnit.OnDamage(self, instigator, amount, vector, damagetype) if self:IsDead() == false and instigator and IsUnit(instigator) then LOG('Taking damage') local myFuel = self:GetFuelRatio() if self.BurnerActive == false and myFuel > 0 then LOG('Engaging Afterburner via OnDamage Event') ### Set flags to true self.BurnerActive = true self.Evade = true ### Kick off Afterburner multi and effects self:ForkThread(self.Afterburner) end end end,
Afterburner = function(self) if not self:IsDead() then if self.BeamExhaustEffectsBag then ### Engine effects clean up EffectUtil.CleanupEffectBag(self,'BeamExhaustEffectsBag') end LOG('Afterburner on') ### Engage Afterburn speed and turn rates self:SetSpeedMult(2.0) self:SetAccMult(2.0) self:SetTurnMult(0.5) ### Afterburn effects and smoke table.insert(self.BeamExhaustEffectsBag, CreateBeamEmitterOnEntity( self, 'afterburner', self:GetArmy(), self.BeamAfterBurner):ScaleEmitter(2.0)) table.insert(self.BeamExhaustEffectsBag, CreateAttachedEmitter(self, 'exhaust', self:GetArmy(), self.ExhaustSmoke):ScaleEmitter(0.5)) ### Play Afterburner sound effects self:PlayUnitSound('Afterburn') ### Get current fuel levels local preBurnFuel = self:GetFuelRatio() LOG('Pre burn fuel: ', preBurnFuel) ### Duration of Afterburn WaitSeconds(2) ### Get the fuel levels post Afterburner local postBurnFuel = self:GetFuelRatio()
### Fuel calculations and Afterburn effect clean up if not self:IsDead() then ### Calculate new fuel levels as per *** BIGO's New ASF MOD *** local newFuelLvl = preBurnFuel - (10 *(preBurnFuel - postBurnFuel)) LOG('Post burn fuel: ', newFuelLvl) if newFuelLvl > 0 then self:SetFuelRatio(newFuelLvl) end if self.BeamExhaustEffectsBag then ### Engine effects clean up EffectUtil.CleanupEffectBag(self,'BeamExhaustEffectsBag') end
### Resets the speed and turn rates self:SetSpeedMult(1.0) self:SetAccMult(1.0) self:SetTurnMult(1.0) LOG('Afterburner Cooldown') ### Short pause between Afterburns WaitSeconds(4) ###Resets Afterburn and Evade triggers if not self:IsDead() then self.BurnerActive = false self.Evade = false LOG('Afterburner off') end end end end, OnKilled = function(self, instigator, type, overkillRatio) if self.BeamExhaustEffectsBag then ### Engine effects clean up EffectUtil.CleanupEffectBag(self,'BeamExhaustEffectsBag') end
### Final command to finish off the fighters death event TAirUnit.OnKilled(self, instigator, type, overkillRatio) end, }
TypeClass = UEA0206
Resin_Smoker
_________________
 Blackhole http://www.youtube.com/watch?v=B3aDT0Ft_Yg WOFhttp://www.youtube.com/watch?v=FVqMqz8PgEc FOD http://www.youtube.com/watch?v=be9cu9UHv-U TML http://www.youtube.com/watch?v=1Apk08LAtxc
Last edited by Resin_Smoker on 09 Apr, 2009, edited 2 times in total.
|
|
| Top |
|
 |
|
Resin_Smoker
|
Posted: 07 Apr, 2009
|
|
Joined: 01 May, 2007 Posts: 4219
|
Lightning / BFG projectiles.Code: # # Aeon "Annihilator" BFG Projectile # Author Resin_Smoker # Projectile based off ideas and scripts from Seiya's lobber mod #
local DefaultProjectileFile = import('/lua/sim/defaultprojectiles.lua') local EmitterProjectile = DefaultProjectileFile.EmitterProjectile local ADisruptorShellProjectile = import('/lua/aeonprojectiles.lua').ADisruptorShellProjectile local EffectTemplate = import('/lua/EffectTemplates.lua') local RandomFloat = import('/lua/utilities.lua').GetRandomFloat local utilities = import('/lua/utilities.lua')
BFGShell = Class(EmitterProjectile) { FxTrails = EffectTemplate.SDFExperimentalPhasonProjFXTrails01, FxTrailScale = 1, FxImpactUnit = EffectTemplate.SDFExperimentalPhasonProjHit01, FxUnitHitScale = 0.5, FxImpactProp = EffectTemplate.SDFExperimentalPhasonProjHit01, FxLandHitScale = 0.5, FxImpactLand = EffectTemplate.SDFExperimentalPhasonProjHit01, FxPropHitScale = 0.5, AttackBeams = {'/mods/4th_Dimension_194/hook/effects/emitters/BFG_lightning_beam_01_emit.bp'},
OnCreate = function(self) EmitterProjectile.OnCreate(self) self:ForkThread(self.BFGThread) end, BFGThread = function(self) WaitTicks(4) local beams = {} local avalibleTargets = {} while true do local instigator = self:GetLauncher() local launcherPos = instigator:GetPosition() local projPos = self:GetPosition() local dist = VDist2(projPos[1], projPos[3], launcherPos[1], launcherPos[3]) local avalibleTargets = utilities.GetEnemyUnitsInSphere(self, self:GetPosition(), dist * 0.25) if dist > 10 and avalibleTargets then if table.getn(avalibleTargets) > 3 then for i = 0, (3 -1) do local ranTarget =Random(1,table.getn(avalibleTargets)) local target = avalibleTargets[ranTarget] DamageArea(instigator,target:GetPosition(),0.01,self.DamageData.DamageAmount*0.025,self.DamageData.DamageType,self.DamageData.DamageFriendly) for k, v in self.AttackBeams do local beam = AttachBeamEntityToEntity(self, -1, target, -1, self:GetArmy(), v) table.insert(beams, beam) self.Trash:Add(beam) end end elseif table.getn(avalibleTargets) <= 3 then for k, v in avalibleTargets do local target = v DamageArea(instigator,target:GetPosition(),0.01,self.DamageData.DamageAmount*0.025,self.DamageData.DamageType,self.DamageData.DamageFriendly) for k, v in self.AttackBeams do local beam = AttachBeamEntityToEntity(self, -1, target, -1, self:GetArmy(), v) table.insert(beams, beam) self.Trash:Add(beam) end end end end WaitTicks(4) for k, v in beams do v:Destroy() end end end,
OnImpact = function(self, TargetType, targetEntity) local rotation = RandomFloat(0,2*math.pi) CreateDecal(self:GetPosition(), rotation, 'crater_radial01_normals', '', 'Alpha Normals', 5, 5, 300, 0, self:GetArmy()) CreateDecal(self:GetPosition(), rotation, 'crater_radial01_albedo', '', 'Albedo', 6, 6, 300, 0, self:GetArmy()) ADisruptorShellProjectile.OnImpact( self, TargetType, targetEntity ) end, }
TypeClass = BFGShell
_________________
 Blackhole http://www.youtube.com/watch?v=B3aDT0Ft_Yg WOFhttp://www.youtube.com/watch?v=FVqMqz8PgEc FOD http://www.youtube.com/watch?v=be9cu9UHv-U TML http://www.youtube.com/watch?v=1Apk08LAtxc
Last edited by Resin_Smoker on 09 Apr, 2009, edited 1 time in total.
|
|
| Top |
|
 |
|
Resin_Smoker
|
Posted: 07 Apr, 2009
|
|
Joined: 01 May, 2007 Posts: 4219
|
Aircraft defensive / tactical teleportation
Code: OnCreate = function(self, builder, layer) AAirUnit.OnCreate(self,builder,layer) ### Are we alive? if not self:IsDead() then
### Global Varible Setup### self.DmgTotal = 0 end end,
OnDamage = function(self, instigator, amount, vector, damagetype) AAirUnit.OnDamage(self, instigator, amount, vector, damagetype)
### Are we alive and what form of damage did we receive if not self:IsDead() and damagetype == 'Normal' then local currentHealth = self:GetHealth() local dmgLimit = self:GetMaxHealth() * 0.1 ### Verify what damaged our fightrer is a valid unit and that the damage amount taken doesnt kill us outright. ### Thus preventing a event from teleportation from triggering during our fighters death. if IsUnit(instigator) and amount < currentHealth then
### Update of global Variables self.DmgTotal = self.DmgTotal + amount
### teleport trigger check if self.DmgTotal >= dmgLimit then CreateAttachedEmitter( self, 'uaa0306', self:GetArmy(), '/effects/emitters/generic_teleportout_01_emit.bp') self:PlayUnitSound('Warp') if table.find(instigator:GetBlueprint().Categories,'AIR') then ### Our fighter teleports tacticaly as a defensive measure vs air units ### It will teleport behind its attacker and retaliate local enemyPos = instigator:CalculateWorldPositionFromRelative({0, 0, -10}) local enemyFacing = instigator:GetOrientation() Warp(self, enemyPos, enemyFacing) IssueAttack({self}, instigator) self:ForkThread(self.Effects) else ### fighter teleports randomly as a defensive measure vs non-air units local location = self:GetPosition() local ranx = location[1] + Random(-25, 25) local rany = location[2] + Random(-25, 25) local destination = {ranx, rany, location[3]} Warp(self,destination) self:ForkThread(self.TeleportEffects) end ### Reset of global Variables self.DmgTotal = 0 end end end end,
TeleportEffects = function(self) if not self:IsDead() then ### Teleportation after effects CreateAttachedEmitter( self, 'uaa0306', self:GetArmy(), '/effects/emitters/generic_teleportin_01_emit.bp') CreateAttachedEmitter( self, 'uaa0306', self:GetArmy(), '/effects/emitters/generic_teleportin_02_emit.bp') CreateAttachedEmitter( self, 'uaa0306', self:GetArmy(), '/effects/emitters/generic_teleportin_03_emit.bp') end end,
_________________
 Blackhole http://www.youtube.com/watch?v=B3aDT0Ft_Yg WOFhttp://www.youtube.com/watch?v=FVqMqz8PgEc FOD http://www.youtube.com/watch?v=be9cu9UHv-U TML http://www.youtube.com/watch?v=1Apk08LAtxc
|
|
| Top |
|
 |
|
DeadMG
|
Posted: 09 May, 2009
|
|
Joined: 15 Feb, 2007 Posts: 20036 Location: Presumably, at the time of posting, his computer.
|
I fixed up the custom icons scripts so that as long as you're using a unique unit ID, the game will always find your custom icons, located in /mods/<modname>/icons/<iconname>.dds
Going to be debuting this script in BO ACU v whatever.
This code goes in /lua/customIcons.lua, then imported into any function that needs it.
Code: local BlueprintLocations = {} # Create a nice global var. function FindBlueprints() for id, mod in __active_mods do local blueprints = DiskFindFiles(mod.location, '*_unit.bp') for id, bp in blueprints do # Now we need to get the unit ID from the file path. string.sub does this job effectively. # Get rid of the string in the second argument. bp = string.gsub(bp, '_unit.bp', '') # URL0001, seven letters, and without _unit.bp, they're the last seven. # This does enforce seven-character unitIDs, but they can be any seven. bp = string.sub(bp, (string.len(bp) - 7)) bp = string.upper(string.gsub(bp,'/','')) BlueprintLocations[bp] = mod.location # Store it off in our pre-defined global. end end end
function GetCustomIconLocation(unitID) unitID = string.upper(unitID) if not BlueprintLocations[unitID] then FindBlueprints() # This should ONLY be called on first finding of a custom icon. No more than once. if not BlueprintLocations[unitID] then LOG("Mod icons folder not found!") LOG(unitID) LOG(repr(BlueprintLocations)) else return BlueprintLocations[unitID] end else return BlueprintLocations[unitID] end end
_________________ I'm watchin you!
|
|
| Top |
|
 |
|
Mooilo
|
Posted: 25 Jul, 2009
|
|
Joined: 08 Jul, 2007 Posts: 5394
|
Making your projectiles not collide with allied units
Put this in the unit's script file, and allied projectiles will go right through it. Enemy projectiles will still hit. Or, you can hook Unit.lua and insert it into the OnCollisionCheck code there, that will make it a global thing.
Code: OnCollisionCheck = function(self, other, firingWeapon) if IsAlly(self:GetArmy(), other:GetArmy()) then ### Allows allies to pass through other allies return false ### Returning false allows the projectile to pass thru else return true ### Projectile impacts normally end end,
_________________
|
|
| Top |
|
 |
|
Manimal
|
Posted: 25 Feb, 2010
|
|
Joined: 11 Apr, 2007 Posts: 1915
|
Manimal's fix that prevents loss of Build Restrictions after an ACU's Enhancement.
I noticed that Build Restrictions made via a custom script are often lost after any ACU was enhanced .
Enhancements were coded by GPG Devs in a raw / rough way.
So I bring there a nice solution.
In my humble opinion ACUs Enahncements should have been coded originaly the way I show up, since it takes in count the probablity of changes made through any mod.
Here's the detailed paortion of the script that can be implemented to any ACU.
Code: UEL0001 = Class( TWalkingLandUnit ) { -- hidden useless part of the code for this post CreateEnhancement = function(self, enh) if enh == 'LeftPod' then -- hidden useless part of the code for this post elseif enh =='AdvancedEngineeringRemove' then local bpEconBR = self:GetBlueprint().Economy.BuildRate if not bpEconBR then return end
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # N.B. : CAUSES THE LOSS OF SPÉCIFIC RESTRICTIONS THAT ARE ADDED VIA ANY MOD # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #self:RestoreBuildRestrictions() #self:AddBuildRestriction( categories.UEF * (categories.BUILTBYTIER2COMMANDER + categories.BUILTBYTIER3COMMANDER) )
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # MANIMAL's FIX #1 PREVENTS THE LOSS OF BUILD RESTRICTIONS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local preReq = bp.Prerequisite local bpPreReq = self:GetBlueprint().Enhancements[preReq] if not bpPreReq then return end local cat = ParseEntityCategory( bpPreReq.BuildableCategoryAdds ) self:AddBuildRestriction( cat )
if Buff.HasBuff( self, 'UEFACUT2BuildRate' ) then Buff.RemoveBuff( self, 'UEFACUT2BuildRate' ) end elseif enh =='T3Engineering' then -- hidden useless part of the code for this post elseif enh =='T3EngineeringRemove' then local bpEconBR = self:GetBlueprint().Economy.BuildRate if not bpEconBR then return end
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # N.B. : CAUSES THE LOSS OF SPÉCIFIC RESTRICTIONS THAT ARE ADDED VIA ANY MOD # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #self:RestoreBuildRestrictions() #self:AddBuildRestriction( categories.UEF * (categories.BUILTBYTIER2COMMANDER + categories.BUILTBYTIER3COMMANDER) )
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # MANIMAL's FIX #2 PREVENTS THE LOSS OF BUILD RESTRICTIONS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --# SUPPRESSION DE 'T3Engineering' local preReq = false local bpPreReq = false if bp.Prerequisite then preReq = bp.Prerequisite bpPreReq = self:GetBlueprint().Enhancements[preReq] if not bpPreReq then return end end local cat = ParseEntityCategory( bpPreReq.BuildableCategoryAdds ) self:AddBuildRestriction( cat ) --# SUPPRESSION DE 'AdvancedEngineering' preReq = false cat = false if bpPreReq.Prerequisite then preReq = bpPreReq.Prerequisite bpPreReq = self:GetBlueprint().Enhancements[preReq] or false if not bpPreReq then return end end cat = ParseEntityCategory( bpPreReq.BuildableCategoryAdds ) self:AddBuildRestriction( cat )
if Buff.HasBuff( self, 'UEFACUT3BuildRate' ) then Buff.RemoveBuff( self, 'UEFACUT3BuildRate' ) end
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # END OF THE FIX FOR Build Restrictions - SCRIPTED by MANIMAL # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
elseif enh =='DamageStablization' then -- hidden useless part of the code for this post end, }
Enjoy the new ACU without undesired behavior ! 
_________________ Console Plus - Solo A.C.U. - Experimental Wars
|
|
| Top |
|
 |
|
Ghaleon
|
Posted: 02 Mar, 2010
|
|
Joined: 13 Jun, 2008 Posts: 729
|
On behalf of Resin_Smoker I've taken a look at properly cloaking the T2 Cybran Stealth Fighter of 4th-Dimension.
I found that below fix will allow proper functionality for all units. Initially meant as a timed exclusive to 4th-Dimension and TVg, I'm releasing this code with permission from Resin_Smoker.
Adding the following bit into your unit.lua will enable cloaking of individual units to work as intended, that is, once they can't be seen anymore, they won't be fired at, even if they uncloak and recloak without Omni coverage. Code: EnableUnitIntel = function(self, intel) if intel and intel == 'Cloak' then if not self.dnt then self:SetDoNotTarget(true) self.dnt = ForkThread(function() WaitTicks(1) self:SetDoNotTarget(false) self.dnt:Destroy() self.dnt= nil end) self.Trash:Add(self.dnt) end end oldUnit.EnableUnitIntel(self, intel) end,
There appears to be also some bit referring to a cloakfield in the Intel tree, if you can point me to units using that bit I can test if above code needs to be expanded.
_________________ TVg V5 Alpha Testers Wanted!
 Bulletstorm released other mods
|
|
| Top |
|
 |
|
Krapougnak
|
Posted: 06 Mar, 2010
|
|
Joined: 21 May, 2008 Posts: 706
|
|
| Top |
|
 |
|
OrangeKnight
|
Posted: 06 Mar, 2010
|
|
| Forum Scout |
 |
 |
Joined: 02 Mar, 2007 Posts: 9003 Location: Ninja Editing Your Post from a Canadian IPhone
|
|
I've added it to the Useful Info Thread under ''Misc"
Mike
_________________ God of Models - Moderator BlackOps Team Twitter
|
|
| Top |
|
 |
|
Ghaleon
|
Posted: 06 Mar, 2010
|
|
Joined: 13 Jun, 2008 Posts: 729
|
|
This thread used to be stickied and ought to again, I myself haven't seen it in the useful info thread.
AKA, people who might need the info might not even see it.
Also non-script postings including this one should not be made into this thread. I request them purged.
_________________ TVg V5 Alpha Testers Wanted!
 Bulletstorm released other mods
|
|
| Top |
|
 |
|
OrangeKnight
|
Posted: 06 Mar, 2010
|
|
| Forum Scout |
 |
 |
Joined: 02 Mar, 2007 Posts: 9003 Location: Ninja Editing Your Post from a Canadian IPhone
|
Ghaleon wrote: This thread used to be stickied and ought to again, I myself haven't seen it in the useful info thread. AKA, people who might need the info might not even see it.
I don't want to clutter up the sticky section of the forum right now, especially with SC2 stuff coming hard and fast, and as I said, I've added it to the Useful Info thread under "Misc"
Mike
_________________ God of Models - Moderator BlackOps Team Twitter
|
|
| Top |
|
 |
|
Ghaleon
|
Posted: 06 Mar, 2010
|
|
Joined: 13 Jun, 2008 Posts: 729
|
|
At the very least, please, clean the non-related posts so this thread remains useful and isn't filled with our non-contributing clutter.
Thank you OrangeKnight!
_________________ TVg V5 Alpha Testers Wanted!
 Bulletstorm released other mods
|
|
| Top |
|
 |
 |
 |
|