Long story short, I'm working on updating the EAF faction, as opposed to building a mod from scratch. Now after reading enough topics here and hunting down my problem I've got a generally good understanding with how most of the scripts work, and even how some of the LUA works.
Now, what I'm trying to figure out is if there is a way with LUA to create an AEmitter at the end of a MOPixels lifetime. What I'm trying to do is make a rail rifle round that inflicts an entry and an exit wound on light units, but getting slowed by heavy armor so that the AEmitter will be created inside the Actor and basically tear them up. I'm trying to use the MOPixels mass, sharpness, and the velocity to determine if it cleanly pierces a light unit or gets bogged down in say "Military Stuff".
The only other idea I would see if I could us CastMORay, and try to use that to find the mass value...and other not fun stuff.
So...really is there a way to have an MOPixel create an AEmitter on death? I've already tried just using an aemitter for the effect but even with hitsmos = 1, it seems to ignore MOs half the time (Not going over 500 vel more like 25-50)
-edit- I thought about trying a timer and running the script from the MOPixel define, but thought that it would cause issues if the MOPixel died before the 10ms timer in the LUA (It might work for penetrating light units, but on heavier units the MOPixel would break apart inside, then the LUAs timer would finish and try to create the AEmitter on the MOPixel, but...with horrible results.)
The LUA I was thinking of
function Create(self) self.XRGTimer = Timer(); end
function Update(self) if self.XRGTimer:IsPastSimMS(10) then local rg = CreateAEmitter("XRG"); rg.Pos = self.Pos; rg.Vel = Vector(0,0); end
Wed Oct 01, 2014 2:09 pm
4zK
Joined: Mon Oct 11, 2010 1:15 pm Posts: 594 Location: Finlandia
Re: Need help with a rail gun.
Oh hey there
Assuming you're new to modding, I wouldn't recommend trying to "update" an older mod to work, even though the changes needed wouldn't even be that hard to do.
Screwing around with existing mods as templates is a good start, though. Applies to both .ini and .lua code. If you're looking to make your own mods though, start with .ini.
Anyway, the lua you have there; currently seems to try to spawn an emitter every 10 MS. It would probably work better like this;
Code:
function Create(self) self.XRGTimer = Timer(); end
function Update(self) if self.XRGTimer:IsPastSimMS(10) then local rg = CreateAEmitter("XRG"); rg.Pos = self.Pos; rg.Vel = Vector(0,0); -- not exactly needed because the velocity is (0,0) by default MovableMan:AddParticle(rg); -- spawn the particle! self.XRGTimer:Reset(); -- reset timer to start counting from zero again end -- this closes "if self.XRGTimer..." end -- this closes "function Update(self)"
Wed Oct 01, 2014 2:56 pm
Rhyssia
Joined: Sun Sep 28, 2014 6:04 pm Posts: 13
Re: Need help with a rail gun.
Thank you for the reply! Im kinda used to LUA scripting so much that I used to script for a Dayz server, so I have a basic understanding. And I've managed to get a good part of that faction mod to work *Decently* I thought it would have been easier to compare the files with base files and other mod files to see how things are done. (Mostly differences in LUA, and how the weapons work and the like)
I *think* I understand the rest of your code but Im not exactly clear on >> MovableMan:AddParticle(rg); (After looking it up, it adds the actual AEmitter?)
Also if I'm reading yours right that will create the AEmitter every 10ms. I'm just trying to add a single AEmitter, that would hopefully spawn once from a MOPixel. Then attach the script to an MOpixel "bullet". The bullet MOPixel is carried inside an LUA script that triggers the creation of the bullet MOPixel on impact with an actor. The LUA script that carries it also sets the velocity. That way I can set the velocity, sharpness, and mass in such a way that it doesn't send any of the actors to orbit. (I was using the firing range scenario and I admit I laughed when I shot a coalition soldier, and watched his helmet fly off and decapitate the guy behind him...I'm guessing it was over the head's gibimpulseforce?)
Wed Oct 01, 2014 4:16 pm
4zK
Joined: Mon Oct 11, 2010 1:15 pm Posts: 594 Location: Finlandia
Re: Need help with a rail gun.
Ah, sorry, I can sort of see what you're going for now.
A simple solution to add particles on "death" through .lua would be on "function Destroy(self)", but that often results in inaccuracy regarding the frame of time that the particle (in this case, AEmitter) would be spawned, i.e. if the pixel goes fast enough, it'll spawn the emitter where the pixel was last "present" before making a wound.
I'm sure that there's probably some way to define the desired effect to only target "heavy" actors, but that requires some extensive scripting and I don't think it's worth it.
For a good example of spawning stuff on a pixel's impact, check out Techion.rte's Dissipate.lua. Its' probably got some unnecessary parts to it, but I'm sure you'll figure out the main purpose of the script. I've used it as a base for stuff like explosive bullets.
Oh yeah, and the "MovableMan:AddParticle(particle)" line is required to spawn the particle that you have defined.
And yeah head accessories make the actors' heads really vulnerable to impulse force, kinda silly imo.
OH; one more thing, if you have trouble with too high recoil, you can define the percentage of actor-inherited recoil from a HDFirearm with a RecoilTransmission value; 1 is 100% (default), 0.5 is 50% etc.)
Wed Oct 01, 2014 4:40 pm
Rhyssia
Joined: Sun Sep 28, 2014 6:04 pm Posts: 13
Re: Need help with a rail gun.
Alright, Hmm. If I understand you correctly I could use something like the following script to spawn the AEmitter on the death of the MOpixel? I dont want the MOPixel to ignore any actors, just attach the AEmitter to the end of the MOPixels "lifetime". The MOpixel running the following code is created by a separate LUA script that starts the MOPixel on the surface of the actor and sets it's velocity and vector starting from that point. This lets me set the velocity to something small, such as 25. Then I can use Mass or Sharpness to get the piercing.
Code:
function Destroy(self) local rg = CreateAEmitter("XRG"); rg.Pos = self.Pos; MovableMan:AddParticle(rg) end
Looking back at it, I think I messed up all that code >.< Maybe something like?
Code:
function Create(self) self.XRGTimer = Timer(); end
function Update(self) if self.XRGTimer:IsPastSimMS(10) then function Destroy(self) local rg = CreateAEmitter("XRG"); rg.Pos = self.Pos; MovableMan:AddParticle(rg) end end
Feel free to tell me to go away until I read more LUA tutorials v.v
I will also start digging around the dissipate.lua. And again thank you!
-edit- P.S. I've also been looking into the dummy destroyer as it seems almost what I had in mind.
Maybe I could just use the AEmitter and use these settings and just drop the LUA?
the function Destroy(self) is a native Cortex Command function, just like the create and update functions, so it should be located outside of those functions by itself. However, there is an obscure bug with the destroy function and spawning particles that sometimes interfers. An easier solution would be to do
Code:
if self.XRGTimer:IsPastSimMS(10) and self.ToDelete then local rg = CreateAEmitter("XRG"); rg.Pos = self.Pos; MovableMan:AddParticle(rg) end
All though you might want to do something like rg.Pos = (self.Pos+self.Vel), to get it to spawn where you want it.
The AEmitter ini code is just code for a standard AEmitter that starts emitting after 10 seconds.
Edit: Removed the lazy copy/paste second if..
Last edited by clunatic on Wed Oct 01, 2014 7:16 pm, edited 1 time in total.
Wed Oct 01, 2014 6:20 pm
Rhyssia
Joined: Sun Sep 28, 2014 6:04 pm Posts: 13
Re: Need help with a rail gun.
Wow Thanks! Ok, so you think I should use something like this?
Code:
function Create(self) self.XRGTimer = Timer(); end
function Update(self) if self.XRGTimer:IsPastSimMS(10) and if self.ToDelete then local rg = CreateAEmitter("XRG"); rg.Pos = (self.Pos+self.Vel); MovableMan:AddParticle(rg) end
As far as as rg.Pos = (self.Pos+self.Vel); is that cleaner than rg.Pos = self.Pos; rg.vel = self.Vel; ?
Also, as far as self.ToDelete, what does it do? Is it set to true when the MOPixel has been removed? If that is the case, couldn't I skip the timer altogether? Alternately, is this possibly going to call for extensive scripting? If so, I appreciate the help but I'll try to read up on more things before attempting to tackle it again.
-edit- P.S. as far as the AEmitter, I don't think that would be the effect I'm looking for exactly. I know that the delay would prevent the emission of the first burst until after that time in MS, but I'm guessing if the AEmitter hits a silverman, doesn't go all the way through and ceased to exist before the 10ms delay, then the emission wouldn't trigger.
Get rid of the second if in the first line, should be something like: "if self.XRGTimer:IsPastSimMS(10 and self.ToDelete then"
ToDelete is exactly what it sounds like, it should be set as true if the object is set to delete next frame (or this frame or whatever).
I'm not sure what the 10MS delay is for, I don't get where this magic number came from but it's probably not needed at all? Seems to me the best way to see if it works and for people to know what else to suggest would be for you to test it and post what happened if it doesn't work well.
Wed Oct 01, 2014 7:11 pm
Rhyssia
Joined: Sun Sep 28, 2014 6:04 pm Posts: 13
Re: Need help with a rail gun.
Thank you Bad Boy. I'll try out the following later and see what happens. The magic 10ms, was what I would have been working with in the Aemitter's emission and just the number I was using.
Code:
function Update(self) if self.ToDelete = true then local rg = CreateAEmitter("XRG"); rg.Pos = (self.Pos+self.Vel); MovableMan:AddParticle(rg); print(test script finished) end
What im hoping for, is that when the MOPixel this script is attached to, ceases to exist. It creates the AEmitter, regardless of where the MOPixel stopped. So far what im getting is damage from the MOPixel it's attached to, and the script doesn't run. So, I figure I'm missing something simple at this point.
Wed Oct 01, 2014 7:15 pm
Arcalane
Joined: Sun Jan 28, 2007 10:32 pm Posts: 1609 Location: UK
Re: Need help with a rail gun.
At first glance I thought I might have something useful for this, but on second reading, the only thing I have is a shell that explodes inside the target no matter what.
Still, you can give it a try if you want! It was designed to simulate a self-propelled explosive round, being for the Imperium's Bolters, but can be repurposed pretty easily and may give you something to work with. It might be possible to grab the 'width' of the actor and only arm if it passes a certain depth, or the density of their materials and only arm if they're suitably tough, or something, I'm not sure.
Code:
function Create(self) self.Velocity = 65; --the bullet's velocity, the ini defined one should be very low (but not too low or you might have weird problems with the AI or the shot being way off-target) self.Sharpness = 15; --the bullet's sharpness, this technically doesn't need to be set here self.ExplosiveName = "190 Charge"; --the name of the AEmitter used for the explosion effect, this has to be emission-based and not auto-gib or else the gun will have friendly fire and self-damage! self.BlastSoundName = "Blast Noise"; --due to a weird bug, the explosive will not reliably trigger its own detonation/gib noise when being force-gibbed in my experience, so a dummy emitter that actively emits the sound instead of causing it on-gib is needed self.acc = 0.2; --the relative acceleration of the round per second - optional, set to 0 for no accel
self.Vel = self.Vel.Normalized*self.Velocity; end
function Update(self) self.Vel = self.Vel.Normalized*(self.Vel.Magnitude*(1+(self.acc*TimerMan.DeltaTimeSecs))); local ray = SceneMan:CastMORay(self.Pos , self.Vel*TimerMan.DeltaTimeSecs*FrameMan.PPM , self.ID ,self.Team, 0, false , 0); if ray ~= 255 or self.Vel.Magnitude < 6 or self.ToDelete == true then local ray2 = SceneMan:CastObstacleRay(self.Pos , self.Vel, Vector() , Vector() , 255 , 0 , 0 , 0); local lr = CreateAEmitter(self.ExplosiveName); lr.Pos = self.Pos+(self.Vel.Normalized*(ray2+6)); lr.Vel = self.Vel*0.175; lr.Team = self.Team; lr.IgnoresTeamHits = true; MovableMan:AddMO(lr); local lr2 = CreateAEmitter(self.BlastSoundName); lr2.Pos = self.Pos+(self.Vel.Normalized*(ray2+6)); lr2.Vel = self.Vel*0.175; lr2.Team = self.Team; lr2.IgnoresTeamHits = true; lr2:GibThis(); MovableMan:AddMO(lr2); self.ToDelete = true; end end
I believe the code was originally provided by either weegee or CC48. I've added my own comments and expanded on theirs a little.
Wed Oct 01, 2014 9:02 pm
Rhyssia
Joined: Sun Sep 28, 2014 6:04 pm Posts: 13
Re: Need help with a rail gun.
That's a really nice script for me to dig apart later, thank you! (It will help when I get to dissecting CastMORay)
I've got something close to what I want working...sort of.
Code:
function Update(self) if self.ToDelete then local rg = CreateAEmitter("XRG"); rg.Pos = (self.Pos); MovableMan:AddParticle(rg) end print("working") end
The issue Im having now is sometimes the round will hit a coalition light soldier, make an entry wound, then an exit wound (Success!) and sometimes gib the little guy into a blood mist (emits 40 MOPixels from the AEmitter, to gib Silver men). Im wondering if this might be an issue with the MOPixel breaking apart too easily, or if Im not giving it enough mass, velocity, or sharpness.
Probably the issue with the previous script was that, unless I'm mistaken, vector addition isn't a thing, you can't do sumvector = vector1 + vector2, you'd instead want to do sumvector = Vector(vector1.X + vector2.X, vector1.Y + vector2.Y). Remember, you can check the console with ~.
This'll set the emitter's position to be in the proper spot instead of slightly behind, probably. As for it still killing light troops, the script'll only trigger if the bullet dies. So yeah, you probably need a tougher bullet, however that's done.
Wed Oct 01, 2014 9:44 pm
Rhyssia
Joined: Sun Sep 28, 2014 6:04 pm Posts: 13
Re: Need help with a rail gun.
@Bad Boy - That resulted in something really unexpected, but really awesome. When the round impacted with an Actor, it would cause the AEmitter to spawn some distance behind them.
Code:
rg.Pos = (self.Pos);
Is working how I would like (By placing the AEmitter on the spot where the round terminates), and it does seem that I need to create a material for the actual bullet, and then I think I've got it. (Assuming I can define a material in a mod ini) I hacked my base.rte/materials.ini to try and add a bullet. So far my initial try worked really good. I just need to tweak it a bit more.
Yeah, I figured that might happen, I was curious to see if it would haha. I suggested it cause clunatic had before and I figured it was worth trying out.
And yes, you can define materials in your own rte, I'm sure there are plenty of examples for you look around for.
Wed Oct 01, 2014 10:19 pm
Rhyssia
Joined: Sun Sep 28, 2014 6:04 pm Posts: 13
Re: Need help with a rail gun.
So it's working beautifully for the most part, I just can't seem to solve the MOPixel (seemingly randomly) blowing up on contact. I can literally shoot through Silver Men, but if I shoot a coalition soldier straight on in the chest, he turns into a red cloud. I'm thinking I could possibly nest the AEmitter, inside two MOPixels, which would seem horribly redundant but would give the lighter actors a second chance. (But still inflicting a wound from the second MOPixel Im guessing.) I've tried making a super material, tried tweaking the sharpness/mass/velocity. But I keep feeling like there's something really simple im not getting.
-edit- Ok after poking around I think I can make it work by hijacking some of the code from the techion's dissipate.lua. Particularly...
Code:
--Check backward. local pos = Vector(); local trace = Vector(self.Vel.X, self.Vel.Y):RadRotate(math.pi) * TimerMan.DeltaTimeSecs * 20; if SceneMan:CastObstacleRay(self.Pos, trace, pos, Vector(), 0, self.Team, 0, 5) >= 0 then --Check that the position is actually strong enough to cause dissipation. trace = SceneMan:ShortestDistance(self.Pos, pos, true); local strength = SceneMan:CastStrengthRay(self.Pos, trace, self.strengthThreshold, Vector(), 0, 0, true); local mo = SceneMan:CastMORay(self.Pos, trace, 0, self.Team, 0, true, 5); if strength or (mo ~= 255 and mo ~= 0) then local effect = CreateAEmitter("Techion.rte/Laser Dissipate Effect"); effect.Pos = pos + Vector(self.Vel.X, self.Vel.Y):RadRotate(math.pi):SetMagnitude(3); effect.Vel = Vector(self.Vel.X, self.Vel.Y):RadRotate(math.pi):SetMagnitude(self.effectSpeed); MovableMan:AddParticle(effect); effect:GibThis(); end end
But Im unsure if I should attach the altered code to an MOPixel fired by the carrier LUA, or add it into the carrier LUA. Im assuming I should cram it in the carrier LUA to make things simple. (The carrier LUA Im using basically just creates the rail gun trail and the MOPixel, and sets the MOPixels velocity, and then I had the small script attached to the MOPixel... but if I can use that code to determine the strength of the material I'm aiming at I could use it to adjust what to create. MOPixel for a weak strength, and an AEmitter for something "Military Stuff" strength.)
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum