Hard Light Productions Forums
Modding, Mission Design, and Coding => The Scripting Workshop => Topic started by: Kusanagi on December 29, 2010, 11:16:11 pm
-
This is split off from a posting in the forums for the Homeworld mod.
I'm trying to use scripting to figure out the best way to make a proximity mine that doesn't just detonate, but will move in to chase a target if it gets too close. I was pointed to this (http://www.hard-light.net/wiki/index.php/Script_-_Proximity_Trigger) script as a starting point. None of the functions in that script work as they're all outdated.
Wondering what I missed, I then went to the scripting tutorial and that too is out of date. This is frustrating as without the examples working, I can't seem to make sense of the scripting output for the 3.6.12 build and 3.6.13 update.
Basically, here's what I would like the following script to do, and I've posted it here from the wiki page.
1) When a mine is dropped off from a player ship, it waits until it is armed (either by arming in the table or in the script)
2) If the mine is armed, get the name of it to see if its a homing mine
3) If it's a mine, see what team it's on
4) Check the distance from it to other ships
5) If a target ship is within 1200 meters and on the enemy team, set the lifetime of the mine to 60 seconds and have it lock on to whatever triggered it
If that can't be done, I would settle for setting the weapon's target to the ship, and then detonating it so a spawn weapon could go chase it using the "inherit parent target" flag in the table.
#Global Hooks
$Simulation:
[
--Get all weapons
for i=1,mn.getNumWeapons() do
weapon = mn.getWeaponByIndex(i)
weapontype = weapon.Class.Name
--Select only mines
if weapontype == "Helios" then
weaponlife = weapon.LifeLeft
--Select only those mines that have been activated (time activation)
if weaponlife < 25 then
weaponteam = weapon.Team
--Start building distance array
for m=1,mn.getNumShips() do
ship = mn.getShipByIndex(m)
shipteam = ship.Team
weaponposition = weapon.Position
shipposition = ship.Position
shipdistance = weaponposition:getDistance(shipposition)
if shipteam ~= weaponteam and shipdistance < 1000 then
weapon.LifeLeft = 0
end
end
end
end
end
]
#End
I'm just learning how to script but the wiki as it stands is much more confusing than helpful :(
-
The script in the wiki is very outdated and some function don't even exist anymore.
Here is a better version I wrote:
#Conditional Hooks
$Application: FS2_Open
$On Game Init:
[
mineName = "Helios" -- <-- Insert wanted name here
activationTime = 25 -- <-- If Weapon-LifeLeft is less than this the mine is activated
detonationDistance = 1000 -- <-- The distance in which the mine will detonate
]
$State: GS_STATE_GAME_PLAY
$On Frame:
[
for i=0,#mn.Weapons do
local weapon = mn.Weapons[i]
if (weapon ~= nil and weapon:isValid()) then
if (weapon.Target == nil) then
if (weapon.Class.Name == mineName) then
if (weapon.LifeLeft <= activationTime) then
for m=0,#mn.Ships do
ship = mn.Ships[m]
if (ship ~= nil and ship:isValid()) then
shipteam = ship.Team
weaponposition = weapon.Position
shipposition = ship.Position
shipdistance = weaponposition:getDistance(shipposition)
if (shipteam ~= weaponteam and shipdistance < detonationDistance) then
weapon.LifeLeft = 0
else
weapon.Target = ship
end
end
end
end
end
end
end
end
]
#End
]
#End
It's largely the same as in the wiki but it will set the weapon to attack the ship and the script will only affect weapons that were fired without a target.
I haven't tested the script in-game but it should work :nervous:
-
Is it possible to spawn mines all around in a given area?
-
Yes, I think it could be doable but it would need some code-changes (unlimited LifeTime for weapons) to act as a "real" minefield.
-
Does it have the potential to slow the game significantly?
-
If it doesn't produce 10000 mines it shouldn't be a problem.
-
I'm interested on this. Do we have a candidate for the role of mine? Those used in the FSPort are a bit too big, IMO.
-
It depends on how large the mine is compared to the ship that launched it. If it's launched by a player, then you would want something small that could target ALL ships.
If its something set down by a larger capital ship, then it could be a ship class set as a cruiser with the kamikaze command set in FRED. If the class of the ship that triggers it isn't a fighter, then simply ordering the mine to attack said ship should cause it to kamikaze.
EDIT: Tried the script and it did nothing. I modified it to the following and it somewhat works.
#Conditional Hooks
$Application: FS2_Open
$On Game Init:
[
mineName = "Homing Mine" -- <-- Insert wanted name here
activationTime = 585 -- <-- If Weapon-LifeLeft is less than this the mine is activated
detonationDistance = 1000 -- <-- The distance in which the mine will detonate
]
$State: GS_STATE_GAME_PLAY
$On Frame:
[
for i=0,#mn.Weapons do
local weapon = mn.Weapons[i]
if (weapon:isValid()) then
if (weapon.Class.Name == mineName) then -- < --Check if the weapon is a mine
if (weapon.LifeLeft <= 585) then -- < --Check if the weapon has been on long enough
for m=0,#mn.Ships do -- < -- Go through the ships
ship = mn.Ships[m]
if (ship ~= nil and ship:isValid()) then
shipteam = ship.Team
shipname = ship.Name
weaponposition = weapon.Position
shipposition = ship.Position
shipdistance = weaponposition:getDistance(shipposition)
if (shipteam ~= weaponteam and shipdistance < detonationDistance) then
weapon.Target = ship
weapon.LifeLeft = 0
gr.drawString(shipname, 100, 100)
end
end
end
end
end
end
end
]
#End
]
#End
The issue is that the mine itself has a velocity of 0, so setting it to chase a target is useless unless there's a way to change its velocity in the tables. Would having the free flight modified in the table work for that?
Having this blow up the mine works to spawn the cluster mine - the only problem is right now is that the mine will track the nearest ship no matter what the distance to the mine is.
Getting closer though!
-
You can manipulate the maximum velocity of the ship via object.Physics.VelocityMax so you could modify the script so a mine targets a ship if it's within a certain distance and then detonate when it's in near enough.
Something like this:
#Conditional Hooks
$Application: FS2_Open
$On Game Init:
[
mineName = "Homing Mine" -- <-- Insert wanted name here
activationTime = 585 -- <-- If Weapon-LifeLeft is less than this the mine is activated
detonationDistance = 500 -- <-- The distance in which the mine will detonate
homingDistance = 4000
]
$State: GS_STATE_GAME_PLAY
$On Frame:
[
for i=0,#mn.Weapons do
local weapon = mn.Weapons[i]
if (weapon:isValid()) then
if (weapon.Class.Name == mineName) then -- < --Check if the weapon is a mine
if (weapon.LifeLeft <= activationTime) then -- < --Check if the weapon has been on long enough
for m=0,#mn.Ships do -- < -- Go through the ships
local ship = mn.Ships[m]
if (ship ~= nil and ship:isValid()) then
local shipteam = ship.Team
local shipname = ship.Name
local weaponposition = weapon.Position
local shipposition = ship.Position
local shipdistance = weaponposition:getDistance(shipposition)
if (shipteam ~= weaponteam) then
gr.drawString(shipname, 100, 100)
if (shipdistance < detonationDistance) then
weapon.LifeLeft = 0 -- Detonate the weapon
else if (shipdistance <= homingDistance) then
weapon.Physics.VelocityMax = ba.createVector(0, 0, 100) -- <-- New velocity (axis might be wrong)
weapon.Target = ship
end
end
end
end
end
end
end
end
end
]
#End
Could you try this?
-
I found out what the problem was initially - you didn't set the weapon.Team in there :lol:
Let me give it another shot. For now, I have the script for a ship class working. You need to have a class of ship with the "cruiser" flag enabled and set the "Kamikaze" flag and damage in FRED to make it work, but so far it works beautifully with some help from The_E.
The only issue is it needs to be modified so it doesn't activate against non-capital ships, or anything with the "fighter" flag really.
#Conditional Hooks
$Application: FS2_Open
$On Game Init:
[
MineClass = "Large Mine" -- <-- Insert name of larger anti-cap-ship mine here
ActivateDistance = 1000 -- <-- The distance in which the mine will detonate
]
$State: GS_STATE_GAME_PLAY
$On Frame:
[
for i=0,#mn.Ships do
local mine = mn.Ships[i]
if (mine ~= nil and mine:isValid()) then
if (mine.Class.Name == MineClass) then --See if it's a mine
if (mine.Target:isValid() == false) then --Check if the mine has a target
for m=0,#mn.Ships do -- Go through the mission ships checking to see if anything is in range
ship = mn.Ships[m]
if (ship ~= nil and ship:isValid()) then
mineteam = mine.Team
shipteam = ship.Team
mineposition = mine.Position
shipposition = ship.Position
shipdistance = mineposition:getDistance(shipposition)
if (shipteam ~= mineteam and shipdistance < ActivateDistance) then --clear the orders and have it attack the ship in range
mine:clearOrders()
mine.Target = ship
shipname = ship.Name
mine:giveOrder(ORDER_ATTACK, ship)
end
end
end
end
end
end
end
]
#End
]
#End
Let me try the latest one you posted for the weapons and I'll get back to you quickly :D Are you ever in IRC?
One last question - how does the runSEXP() command syntax work? I assume you have to insert the string of the SEXP, and other arguements are the values plugged into it?
-
I found out what the problem was initially - you didn't set the weapon.Team in there :lol:
:wtf: Maan, I'm dumb...
The only issue is it needs to be modified so it doesn't activate against non-capital ships, or anything with the "fighter" flag really.
Take a look at Shipclass.Type, maybe this is what you want.
One last question - how does the runSEXP() command syntax work? I assume you have to insert the string of the SEXP, and other arguements are the values plugged into it?
I think it the same syntax as in the normal mission files.
Are you ever in IRC?
Nearly all time... ;)
-
I found out what the problem was initially - you didn't set the weapon.Team in there :lol:
:wtf: Maan, I'm dumb...
The only issue is it needs to be modified so it doesn't activate against non-capital ships, or anything with the "fighter" flag really.
Take a look at Shipclass.Type, maybe this is what you want.
One last question - how does the runSEXP() command syntax work? I assume you have to insert the string of the SEXP, and other arguements are the values plugged into it?
I think it the same syntax as in the normal mission files.
Are you ever in IRC?
Nearly all time... ;)
Shipclass.type seems to fetch the +type field in the table used in techroom descriptions, I think.
-
Is it possible to use retextured Type One countermeasures as mines?
-
I actually have semi-working versions of the scripts done. The weapon mine works right now. The only issue is making it look a bit prettier but it will track anything that comes close and go after it. You can specify the weapon in question so using a countermeasure POF would be fine in the table.
The second version of the mine script is an actual ship that you place in FRED like a sentry gun that will go kamikaze into anything that gets near it. The problem with this script right now however is that it can be triggered by fighters, but the engine doesn't allow craft to try to kamikaze other fighters. This is why I'm trying to figure out the ship type, so it can go after everything else but player-pilotable craft.