View unanswered posts | View active topics It is currently Tue Apr 16, 2024 7:56 am



Reply to topic  [ 29 posts ]  Go to page Previous  1, 2
 GetDataModule, or some other way to find all modules 
Author Message

Joined: Fri Sep 10, 2010 1:48 am
Posts: 666
Location: Halifax, Canada
Reply with quote
Post Re: New issue
Just to get a bit of clarification on how this works, is it as follows?
1. Press a button to run this function, the first time it saves all the actors.
2. Press a button (presumably the same one) which then loads all the actors.

In that case, I'm not sure why it's giving issues (though maybe I'm just rusty with lua) and I don't entirely understand what you're describing about the printing (hence the previous questions).

Sorry if this is kinda messy, my internet's acting up so I wrote it all in a text file and haven't taken a look to see if it came out decently.

All I can do is point out a few possible issues and maybe that'll help you fix it.

1. You don't seem to check if the actor is alive when saving it. That's not really an issue too much, but it could cause odd behaviour. If MovableMan:IsActor(Act) will solve that.

2. This probably won't work, but sometimes I've run into weird errors where saving an actor's position directly didn't work well. Try saving it as a a vector, i.e. ... = Vector(Act.Pos.X, Act.Pos.Y);

3. If you haven't already, you should drop some prints in the saving part of things, to be sure everything's saving correctly. Figuring out where exactly the problem lies is key to figuring out what's causing it.

Other than this, a few things that might make your life easier:
1. You forgot to save health values, kinda important haha.

2. You could really have all of those table variables in one table. You can have multi-dimensional tables (i.e. tables within tables). While this may sound horrible, it's pretty convenient. Basically somewhere in your main scene you'd say something like self.SavedActorsInfo = {{}}; So you set up a table inside the table. Then you'd have self.SavedActorsInfo[#self.SavedActorsInfo+1][1] = Act.Pos;
Alternatively, and this is the version that'd actually save you a few lines, setup: self.SavedActorsInfo = {};
And do self.SavedActorsInfo[#self.SavedActorsInfo+1] = {Act.Pos, Act.PresetName, Act.Team,...};
If remembering numbers is hard, you can also use names, which is a lot nicer to read. Setting it up with a table inside a table {{}} you'd use self.SavedActorsInfo[###].Pos = ..., which is short form for self.SavedActorsInfo[###]["pos"] = Act.Pos; Similarly, you can call it with self.SavedActorsInfo[###].Pos. Basically it's a lot like if they were self variables or something. Anyway, to make this rather long block of text short, you can save a bit of space that way.
And, cause I'm sure I did a kind of confusing job explaining, here's a link to all the info you need on tables (though I'll admit I found it really confusing when I was first figuring them out): http://lua-users.org/wiki/TablesTutorial

3. To answer your question, yes you can combine a brain check with a playercontrolled check. In fact you could do this:
if not Act:HasObjectInGroup("Brains") and not Act:IsPlayerControlled() and Act.ClassName == "AHuman" and MovableMan:IsActor(Act) then...

4. To get it as self, simply put self in the brackets for the function when writing it and calling it. So your function would look like function SaveActors(self). Alternatively, make it a function of Carnage by writing it like you did Update and so on - function Carnage:SaveActors(). I didn't realize CC's lua activities' variables were public or protected or whatever so they could be accessed how you've done it, that's cool.


Sun Sep 22, 2013 12:31 am
Profile

Joined: Fri Nov 23, 2012 5:42 am
Posts: 143
Reply with quote
Post Re: New issue
Bad Boy wrote:
Just to get a bit of clarification on how this works, is it as follows?
1. Press a button to run this function, the first time it saves all the actors.
2. Press a button (presumably the same one) which then loads all the actors.


Yup, that's the idea.

Bad Boy wrote:
1. You don't seem to check if the actor is alive when saving it. That's not really an issue too much, but it could cause odd behaviour. If MovableMan:IsActor(Act) will solve that.


Yeah, I should really include that.

Bad Boy wrote:
2. This probably won't work, but sometimes I've run into weird errors where saving an actor's position directly didn't work well. Try saving it as a a vector, i.e. ... = Vector(Act.Pos.X, Act.Pos.Y);


This actually fixed the problem. No idea why and I feel a bit stupid for not trying it myself. I really thought this would do the exact same thing as Act.Pos.

Bad Boy wrote:
3. If you haven't already, you should drop some prints in the saving part of things, to be sure everything's saving correctly. Figuring out where exactly the problem lies is key to figuring out what's causing it.


Yeah, I did, print(Carnage.SavedActorsPos[i]) printed the right vector in the save part, but while loading it gave (0,0).

Bad Boy wrote:
Other than this, a few things that might make your life easier:
1. You forgot to save health values, kinda important haha.


I deliberately left it out. Saving health is easy enough, but I don't think it makes sense unless you also save limbs, attachments and wounds. And that is just a bit too much effort and maybe even impossible. In any case the whole point of the saving and loading is more than you can easily set up your own scenarios and then reset them at the push of a button.

Bad Boy wrote:
2. You could really have all of those table variables in one table. You can have multi-dimensional tables (i.e. tables within tables). While this may sound horrible, it's pretty convenient. Basically somewhere in your main scene you'd say something like self.SavedActorsInfo = {{}}; So you set up a table inside the table. Then you'd have self.SavedActorsInfo[#self.SavedActorsInfo+1][1] = Act.Pos;
Alternatively, and this is the version that'd actually save you a few lines, setup: self.SavedActorsInfo = {};
And do self.SavedActorsInfo[#self.SavedActorsInfo+1] = {Act.Pos, Act.PresetName, Act.Team,...};
If remembering numbers is hard, you can also use names, which is a lot nicer to read. Setting it up with a table inside a table {{}} you'd use self.SavedActorsInfo[###].Pos = ..., which is short form for self.SavedActorsInfo[###]["pos"] = Act.Pos; Similarly, you can call it with self.SavedActorsInfo[###].Pos. Basically it's a lot like if they were self variables or something. Anyway, to make this rather long block of text short, you can save a bit of space that way.
And, cause I'm sure I did a kind of confusing job explaining, here's a link to all the info you need on tables (though I'll admit I found it really confusing when I was first figuring them out): http://lua-users.org/wiki/TablesTutorial


This sounds like exactly what I need, but I'm still not quite sure how it works (and yeah, the link doesn't really help me much).

So if I do self.SavedActorsInfo[#self.SavedActorsInfo+1] = {Act.Pos, Act.PresetName, Act.Team,...}, does it save the table with pos, etc in slot one of SavedActorsInfo?

So could I then recall it with something like this:

for i = 1, #Carnage.SavedActorsInfo do
NewActor.Pos = Carnage.SavedActorsInfo[i][1]
NewActor = CreateAHuman(Carnage.SavedActorsInfo[i][2])
end

Bad Boy wrote:
3. To answer your question, yes you can combine a brain check with a playercontrolled check. In fact you could do this:
if not Act:HasObjectInGroup("Brains") and not Act:IsPlayerControlled() and Act.ClassName == "AHuman" and MovableMan:IsActor(Act) then...


Thanks, I just wasn't sure what the syntaxt was with if not statements. I'll leave out the classname part for now though, so I can throw in an else for crabs.

Bad Boy wrote:
4. To get it as self, simply put self in the brackets for the function when writing it and calling it. So your function would look like function SaveActors(self). Alternatively, make it a function of Carnage by writing it like you did Update and so on - function Carnage:SaveActors(). I didn't realize CC's lua activities' variables were public or protected or whatever so they could be accessed how you've done it, that's cool.


Ah ok, I still don't quite get why I couldn't use self in the first place though. And yeah, I didn't know activities variables could be accessed like this either, it was just something I tried after I got an error that a self.variables was nil.

Anyway, thanks yet again for the help. Much appreciated!


Tue Sep 24, 2013 5:58 pm
Profile
Data Realms Elite
Data Realms Elite
User avatar

Joined: Wed Sep 05, 2007 4:14 am
Posts: 3966
Location: Canadida
Reply with quote
Post Re: New issue
clunatic wrote:
Bad Boy wrote:
2. You could really have all of those table variables in one table. You can have multi-dimensional tables (i.e. tables within tables). While this may sound horrible, it's pretty convenient. Basically somewhere in your main scene you'd say something like self.SavedActorsInfo = {{}}; So you set up a table inside the table. Then you'd have self.SavedActorsInfo[#self.SavedActorsInfo+1][1] = Act.Pos;
Alternatively, and this is the version that'd actually save you a few lines, setup: self.SavedActorsInfo = {};
And do self.SavedActorsInfo[#self.SavedActorsInfo+1] = {Act.Pos, Act.PresetName, Act.Team,...};
If remembering numbers is hard, you can also use names, which is a lot nicer to read. Setting it up with a table inside a table {{}} you'd use self.SavedActorsInfo[###].Pos = ..., which is short form for self.SavedActorsInfo[###]["pos"] = Act.Pos; Similarly, you can call it with self.SavedActorsInfo[###].Pos. Basically it's a lot like if they were self variables or something. Anyway, to make this rather long block of text short, you can save a bit of space that way.
And, cause I'm sure I did a kind of confusing job explaining, here's a link to all the info you need on tables (though I'll admit I found it really confusing when I was first figuring them out): http://lua-users.org/wiki/TablesTutorial


This sounds like exactly what I need, but I'm still not quite sure how it works (and yeah, the link doesn't really help me much).

So if I do self.SavedActorsInfo[#self.SavedActorsInfo+1] = {Act.Pos, Act.PresetName, Act.Team,...}, does it save the table with pos, etc in slot one of SavedActorsInfo?

So could I then recall it with something like this:

for i = 1, #Carnage.SavedActorsInfo do
NewActor.Pos = Carnage.SavedActorsInfo[i][1]
NewActor = CreateAHuman(Carnage.SavedActorsInfo[i][2])
end

Hum,

It would save the table \{Act.Pos, Act.PresetName, Act.Team,...}\ in \self.SavedActorsInfo[#self.SavedActorsInfo+1]\
So that mock-script would define a \NewActor\, \Carnage.SavedActorsInfo[i][2]\, at \Carnage.SavedActorsInfo[i][1]\, to my knowledge and given \[i][1]\ is a *.pos, and \[i][2]\ is a *.presetname.

Past that, you can find a way to save things like inventories [like CC48's Repair Kit], health, and remaining limbs [like in TLB's(?) mission, The Reject]. /etc/etc


Wed Sep 25, 2013 2:45 am
Profile

Joined: Fri Sep 10, 2010 1:48 am
Posts: 666
Location: Halifax, Canada
Reply with quote
Post Re: New issue
Foa wrote:
clunatic wrote:
This sounds like exactly what I need, but I'm still not quite sure how it works (and yeah, the link doesn't really help me much).

So if I do self.SavedActorsInfo[#self.SavedActorsInfo+1] = {Act.Pos, Act.PresetName, Act.Team,...}, does it save the table with pos, etc in slot one of SavedActorsInfo?

So could I then recall it with something like this:

for i = 1, #Carnage.SavedActorsInfo do
NewActor.Pos = Carnage.SavedActorsInfo[1]
NewActor = CreateAHuman(Carnage.SavedActorsInfo[i][2])
end

Hum,

It would save the table \{Act.Pos, Act.PresetName, Act.Team,...}\ in \self.SavedActorsInfo[#self.SavedActorsInfo+1]\
So that mock-script would define a \NewActor\, \Carnage.SavedActorsInfo[i][2]\, at \Carnage.SavedActorsInfo[i][1]\, to my knowledge and given \[i][1]\ is a *.pos, and \[i][2]\ is a *.presetname.

Past that, you can find a way to save things like inventories [like CC48's Repair Kit], health, and remaining limbs [like in TLB's(?) mission, The Reject]. /etc/etc
I don't really... know what this means (why the \s?) but yes clunatic, that's how it's done and that should work perfectly. You may want to include the RTE to find the actor in when creating the actor, in case of duplicate actor names but otherwise there should be no issues.

As for saving which limbs actors are missing, that's not so hard in recent versions since someone made easily accessible properties for their limbs. Take a look at the wiki here: http://wiki.datarealms.com/LuaDocs/AHuman. You can easily set up another table inside each actor's table info with true or false for whether or not they have each limb i.e. something like:
Code:
self.SavedActorsInfo[#self.SavedActorsInfo+1] = {Act.Pos, Act.PresetName, Act.Team, {Act.FGArm=nil, Act.BGArm=nil, Act.FGLeg=nil, Act.BGLeg=nil}

This [i]should flag true when the limb no longer exists, though I haven't tested it so that'd be up to you. After that you'd just run through it:
Code:
for i = 1, #Carnage.SavedActorsInfo do
   NewActor.Pos = Carnage.SavedActorsInfo[i][1]
   NewActor = CreateAHuman(Carnage.SavedActorsInfo[i][2])
   ...
   MovableMan.AddActor(NewActor);
   if Carnage.SavedActorsInfo[i][#where limb table is stored][j] == true then
         NewActor.FGArm.ToDelete = true;
   end
   ...
end


You couldn't use self because self is simply a pointer to whatever's running the function. So when you're running an activity function, self is the activity, when you're running an actor function, self is the actor. The function you have here is in the same .lua file as the activity but it is just a standalone function, so self in that case points to something else or maybe to nothing (I'm not actually sure). Thus you can either take in self as an argument for the function i.e. function DoStuff(self) -- so self becomes a variable in the function, much like NewActor or whatever. Or you can write is as an activity function, i.e. function ActivityName:DoStuff() so it's treated in the same way your update function or your start or end activity functions are treated, and self will point to the activity.

As for the table stuff I talked about, pm me, I'll try to give you a proper explanation of them with decent readability and stuff. Also keep practicing table stuff, advancing when you get the hang of it and want to try harder stuff, that's really the only way to get comfortable with it.


Wed Sep 25, 2013 4:09 am
Profile
Data Realms Elite
Data Realms Elite
User avatar

Joined: Wed Sep 05, 2007 4:14 am
Posts: 3966
Location: Canadida
Reply with quote
Post Re: New issue
It's to differentiate text from terms. :v

Code:
self.SavedActorsInfo[#self.SavedActorsInfo+1] = { Act.Pos, Act.PresetName, Act.Team, { Act.FGArm=nil, Act.BGArm=nil, Act.FGLeg=nil, Act.BGLeg=nil } }

ftfy
The inventory would be some list that's iterated through when recreating the actor... beware that precedence matters [so whatever is loaded first will be used first... it's an issue with the base.rte shotgun and the coalition.rte shotgun].

... For the most part, ask CaveCricket about it.


Wed Sep 25, 2013 5:46 am
Profile

Joined: Fri Sep 10, 2010 1:48 am
Posts: 666
Location: Halifax, Canada
Reply with quote
Post Re: New issue
Oh okay, fair enough I guess. No one here is a computer though (I assume) so using escape characters or whatever to specify stuff seems overly convoluted. But maybe that's just me.

Thanks for the bracket correction though :) Typos are always annoying when you're trying to instruct on something haha.

As for inventory, yeah, the only method I can think of is CaveCricket's. Basically you make a junk item (in his case it was the ronin rock) as your starting point, cycle through the inventory saving all the items, then readd them to the new actor. Foa do you know if he solved the issue with rtes (i.e. the shotgun issue you mentioned)? I'm curious as to whether or not there's a way to access an item's rte (I assume there must be).


Wed Sep 25, 2013 8:36 pm
Profile
Data Realms Elite
Data Realms Elite
User avatar

Joined: Wed Sep 05, 2007 4:14 am
Posts: 3966
Location: Canadida
Reply with quote
Post Re: New issue
It was at one point I think, but that was it was used for the revive script around the time of Zombie's '09, that's a long time ago, but I think you can define the rte they can come from... but that's my not-so photographic memory, go bother CaveCricket for that!

The quick solution is to not name your guns like other people does, add in underscores or whitespace characters or something, but that assumes people aren't going to use it with other mods and not going to complain about it. :v

If it's a total crap shoot, then it's a total crap shoot, no use moaning about it than to just admit it and admit to finding no way around it.


Thu Sep 26, 2013 4:41 am
Profile
User avatar

Joined: Tue Jun 12, 2007 11:52 pm
Posts: 13143
Location: Here
Reply with quote
Post Re: New issue
There's no simple way to do it, but what you can do is first record the PresetName, ClassName, and some unique variable on the MO (like gold cost, don't use Mass 'cause that can get screwy sometimes in my experience), and then do a search in every RTE. When you find a match to the PresetName and ClassName, compare the unique variable, and if it matches, that's your item.


Fri Sep 27, 2013 1:38 am
Profile

Joined: Fri Nov 23, 2012 5:42 am
Posts: 143
Reply with quote
Post Re: New issue
Damn, so there's no easy way to get or compare the module of actors? I was hoping to add a "randomise teams by module" function, so you could put down 4 groups of actors from different techs and then just press a button to change the teams and see which tech survives the carnage. That's apparently going to be a bit more complicated than I expected...

How does the GetEntityDataLocation function work? I tried:

print(PresetManager:GetEntityDataLocation(Act.ClassName,Act.PresetName))

But that just gave me the error:

ERROR: no overload of 'PresetManager:GetEntityDataLocation' matched the arguments (<PresetManager>, string, string)
candidates are:
PresetManager:GetEntityDataLocation(string, string, number)

ClassName clearly isn't a valid argument, so what am I supposed to use? Actor, MOSRotating, or even MovableObject?

As for checking the module on guns, is that really worth it? If you have 6 actors with a primary and secondary weapon that's 12 checks that need to be done, just to avoid some confusion with badly named weapons. And 6 actors is on the low side of what I've been using it for..

As for the save/load function, I have now updated it to use the tables within tables method. I'm using Weegee's getinventory function from: http://forums.datarealms.com/viewtopic.php?f=73&t=31975 to handle the weapons and that seems to work just fine. Next up is multiple save slots, which should be easy to do.

No saving health yet, I'm still not entirely convinced it's properly doable or even needed. HP is easy, limbs are doable, attachables might be (by checking ID's, which has it's problems with HitsMOs and GetsHitByMOs), but wounds are the issue. I was under the impression that wounds can't be accessed via lua? More importantly, I wonder if saving HP is needed. The idea I had with the save/loading was more that you could build a scenario (like the 4 groups of actors from different techs example) and easily reset it at the push of a button. Another example would be building a bunker, filling it with actors, changing their team to an enemy one, fight your way through that bunker and then reset it at the push of a button if you want to have another go. Saving HP just doesn't seem that important in those examples and the effort vs reward just means I'm not convinced it's worth it.


Fri Sep 27, 2013 4:50 pm
Profile
Data Realms Elite
Data Realms Elite
User avatar

Joined: Wed Sep 05, 2007 4:14 am
Posts: 3966
Location: Canadida
Reply with quote
Post Re: New issue
Make it more worthwhile to play the game than to save scum, that's pretty much how you decrease piracy, by not being a ♥♥♥♥ about it.

Maybe set milestones that are the only place to save at, and make restarting interesting.


Sat Sep 28, 2013 2:01 am
Profile

Joined: Fri Sep 10, 2010 1:48 am
Posts: 666
Location: Halifax, Canada
Reply with quote
Post Re: New issue
@Clunatic, I've never used it so I may be mistaken but I think you have most of the right arguments, you just have to iterate through all the modules, i.e.
Code:
for i = 1, PresetMan.GetTotalModuleCount() do
   PresetMan.GetEntityDataLocation(Act.ClassName, Act.PresetName, i)
end
Or of course if you know the module id of the rte you want you can just use that instead of iterating through them all.


Sat Sep 28, 2013 2:32 pm
Profile

Joined: Fri Nov 23, 2012 5:42 am
Posts: 143
Reply with quote
Post Re: New issue
Sorry, GTA 5 got in the way of my progress.

Anyway, thanks Bad Boy, your code was nearly right and I managed to figure out the rest.

For what ever reason, iterating through all data modules gives me this crash:


But this code:

Code:
   for i = 1, (PresetMan:GetTotalModuleCount()-1) do
      Act.TempModule = PresetMan:GetEntityDataLocation(Act.ClassName, Act.PresetName, i)
      local number1, number2 = string.find(Act.TempModule, ".rte")
      if number2 ~= nil then                  
         local TempModule = string.sub(Act.TempModule, 1, number2)
         Act.Module = TempModule
      end
   end


Gets me a proper blabla.rte string that I can use and I learned to use string.find and sub at the same time.


Sat Oct 19, 2013 7:43 pm
Profile

Joined: Fri Sep 10, 2010 1:48 am
Posts: 666
Location: Halifax, Canada
Reply with quote
Post Re: New issue
Yeah, lua loops start at 1 and end at the value whereas C++ (and a lot of other languages) loops start at 0 and end at the value - 1. So a table t with 3 elements in lua would have t[1], t[2] and t[3], whereas in C++, etc it'd have t[0], t[1] and t[2]. Since I didn't even consider that, my code kept going beyond the number of modules.
On that note, your for loop should technically start at 0, but since 0 is probably base.rte I doubt it really matters.


Sun Oct 20, 2013 2:27 am
Profile

Joined: Fri Nov 23, 2012 5:42 am
Posts: 143
Reply with quote
Post Re: New issue
Hi guys, I have yet another lua question that I haven't been able to answer myself: Is there any way to get the names of all the modules currently loaded? GetDataModule is the only function that I've found that seems like it would be able to do that, but it doesn't seem to work. According to the console it only accepts a number as an argument, but that just crashes CC instantly.

So, can anyone confirm that GetDataModule isn't working and/or is there some other way to get all the modules currently loaded?


Sun Feb 09, 2014 10:58 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 29 posts ]  Go to page Previous  1, 2

Who is online

Users browsing this forum: No registered users


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

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware for PTF.
[ Time : 0.057s | 15 Queries | GZIP : Off ]