ID:158907
 
Hello. I am making a star wars game and thus it needs space travel. I already figured out how I want to do it.. but I ran into a snag and want to know how to get past it. The reason I didn't put this in code problems was because along with this comes something I really need to know how to do.

Right now my code is as follows:
atom/var/obj/ship
turf
Ships
controll_panel
icon='inner ship.dmi'
icon_state="control panel"
density=1
verb
Controls(mob/M)
set src in oview(1)
M=usr.Ship
if(usr.key==M.Pilot)
if(M.Where=="Planet")
usr.Options=input("Do you wish to ascend?","Ascend?") in list("Yes","No")
if(usr.Options=="No")
return
else
M.Ox=M.x
M.Oy=M.y
M.Oz=M.z
M.loc=locate(35,185,3)
M.Where="Orbit"
usr<<"The [M.Name] has moved to Orbit."
return
if(M.Where=="Orbit")
usr.Options=input("Do you wish to descend or pilot?","Descend/Pilot?") in list("Descend","Pilot","Cancel")
if(usr.Options=="Cancel")
return
if(usr.Options=="Descend")
M.loc=locate(M.Ox, M.Oy, M.Oz)
M.Where="Planet"
return
if(usr.Options=="Pilot")
if(usr.Piloting==0)
usr.Piloting=1
usr.client.eye=M
usr.client.cont=M
usr.client.perspective=EYE_PERSPECTIVE
return
else
usr.Piloting=0
usr.client.eye=usr
usr.client.cont=usr
usr.client.perspective=EYE_PERSPECTIVE
mob
var
Ship
Piloting
Options
Name
Owner
Pilot
Access
Where
Ox
Oy
Oz

Ships
Deadly_Lion
icon='ships.dmi'
icon_state="4"
Name="Deadly Lion"
Where="Planet"
Owner="VolksBlade"
Pilot="VolksBlade"
Access= list("VolksBlade")
verb
Enters()
set name="Enter"
set src in oview(1)
if(usr.key in src.Access)
usr.Ship=src
usr.loc=locate(121,108,2)


For that bit it is a but weird to me.. I have it set and all of that, and it works, it DOES work.. but if you save and relog and go to pilot the ship again, it goes and brings you to a black screen as if ship is not specified. The only reason I can think of that would be what is causing it is the atom is not saving, as it is a atom var and not a mob var.

Onto my second thing, the actual "How To..?"
This game is supposed to be realistic, this feature would add realism, and add immersion (good reason right?) well I need to generate a set layout onto a certain Z on my map file so that when a player say buys a ship a new interior of the ship will be made and all of that. I have seen some demo's showing how to do that but they were really complicated to me, anyone care to explain to me how to do this simply?

Third thing, how would I change from one Status layout to another? Say the player starts piloting, instead of his stats and info in the Status tab it will be the Status of the ship? Is it even possible?

Thanks.
VolksBlade wrote:
Hello. I am making a star wars game and thus it needs space travel. I already figured out how I want to do it.. but I ran into a snag and want to know how to get past it. The reason I didn't put this in code problems was because along with this comes something I really need to know how to do.
[....Snip....]
For that bit it is a but weird to me.. I have it set and all of that, and it works, it DOES work.. but if you save and relog and go to pilot the ship again, it goes and brings you to a black screen as if ship is not specified. The only reason I can think of that would be what is causing it is the atom is not saving, as it is a atom var and not a mob var.

Onto my second thing, the actual "How To..?"
This game is supposed to be realistic, this feature would add realism, and add immersion (good reason right?) well I need to generate a set layout onto a certain Z on my map file so that when a player say buys a ship a new interior of the ship will be made and all of that. I have seen some demo's showing how to do that but they were really complicated to me, anyone care to explain to me how to do this simply?

Third thing, how would I change from one Status layout to another? Say the player starts piloting, instead of his stats and info in the Status tab it will be the Status of the ship? Is it even possible?

Thanks.

First, you already have a ship variable defined for atoms, why re-define it (but capitalized) for mob?

Second, you shouldn't lump ship variables on the basic mob type. Instead, you already have a mob/Ships, why not define variables at that level?

mob
var
piloting

Ships
var
pilot
access
//etc


Third, as you have a reference variable, simply use that to output status messages.

All in all, you're doing this the hard way :) Try organizing things a little more logically (for example, anything that references a ship should be expecting a mob/ship, or some such, instead of just mob). As it stands you could technically pilot another player!

If you're using statpanels (which I recommend against now that we have interface controls), you might try this:
mob
Stat()
if(stapanel("Status"))
if(src.piloting && src.ship)
//output ship status stuff here
else
//output player status stuff here


Good to see that there'll be a use for my revamping of the vehicle library =P
In response to CriticalBotch
Yeah I know I should have put those variables under Ship but I don't know what I was thinking >.<

Well I used the mob var Ship to see if it would be saved and then be able to be drawn on when trying to pilot again when you relogged, but just like with the Atom it didn't save or it didn't load because when you go to pilot again it just shows a black screen as if you was seeing nothing.

(Pilot other users FTW) I do not know how to use the Interface stuff as well as others so I am just going to stick with the statpanels for right now.

Thanks!
In response to VolksBlade
I have it set and all of that, and it works, it DOES work.. but if you save and relog and go to pilot the ship again, it goes and brings you to a black screen as if ship is not specified. The only reason I can think of that would be what is causing it is the atom is not saving, as it is a atom var and not a mob var.

Right - so the issue probably has nothing to do with the object structure, it would instead have to do with the routines you're using for saving and loading. Somewhere in there, you're not reloading what you need to reload where you need to reload it.

This game is supposed to be realistic, this feature would add realism, and add immersion (good reason right?) well I need to generate a set layout onto a certain Z on my map file so that when a player say buys a ship a new interior of the ship will be made and all of that. I have seen some demo's showing how to do that but they were really complicated to me, anyone care to explain to me how to do this simply?

There's a few ways you can do it, but they basically all boil down to having a copy of a ship interior somewhere that you copy onto a new map.

My preferred method is to actually use a map as a template, and this map is one players should never travel to.

    /* BuildFacility spawns a number of nanites which attempt to carve out the facility based off of the type of facility it is.
Facility plans are taken from map 3. BuildFacility contains where in map 3 they can be taken based off type, and spawns
the nanite mobs to carry out the plans. */


proc/BuildFacility(var/tmp/list/turf/myTurfs)
// First we send out nanites to construct the sector barriers:

var/list/turf/myPlan[] = new/list()

switch (type)
if (/mob/device/sector/entrance)
myPlan = block(locate(1,1,3),locate(10,10,3))

else
DebugMsg("[type].BuildFacility() unknown type.")
return(0)

if (myPlan.len == 0)
DebugMsg("BuildFacility: zero length plan.")
return(0)

if (myPlan.len != myTurfs.len)
DebugMsg("[type].BuildFacility(): myPlan.len [myPlan.len] incongruent with myTurfs.len [myTurfs.len].")
return(0)
else
for (var/tmp/increment = 1,increment <= myPlan.len,increment++)
new/mob/nanite(src,myTurfs[increment],myPlan[increment])

return(1)

In this code, I have map 3 actually contain the template for a base entrance across blocks 1,1 through 10,10. This routine actually passes the instructions on creating the facility to a mob whose eventual purpose is to execute:
new thingToBuild.type(locToBuildOn)

It works like a charm. Of course, having a mob do this is unnecessary, you can just stick the new.type directly into the code above as a replacement for new/mob/nanite.

If you didn't want to copy this information from a map, you could also just have all the information you needed to reproduce the thing stored in the rotuine that does the creating... but the nice thing about reproducing from a map is that you can use the map builder to create the template from which they originate.

The tricky business at this point is actually allocating whole new maps and de-allocating them when you're not using them. That's quite a can of worms, and my advice is not to tackle it yourself. A good routine to do this for you is Lummox JR's SwapMaps. If you're looking to make your own routines, at least consider reverse-engineering one like this.
In response to Geldonyetich
Geldonyetich wrote:
The tricky business at this point is actually allocating whole new maps and de-allocating them when you're not using them. That's quite a can of worms, and my advice is not to tackle it yourself. A good routine to do this for you is Lummox JR's SwapMaps. If you're looking to make your own routines, at least consider reverse-engineering one like this.

I generally recommend using SwapMaps for any task in which you need to dynamically add/remove, load/save maps.

There's a minor bug with block() right now that will flip out if you try to use multi-level maps too much, but that will be fixed in the next release.
You've got a number of really weird habits there. First off is that you don't seem to understand that variables can actually be declared within procs, leading you to do things like:

                Controls(mob/M)
set src in oview(1)
M=usr.Ship


That's wrong. This would be right:

                Controls()
set src in oview(1)
var/mob/M=usr.Ship


You make a similar mistake with the Options variable. Simply declare var/Options when you need it rather than adding another variable to every mob in the game.

Next, you're abusing the HELL out of the return statement. While I don't entirely agree with the school of thought that there should only be ONE exit point from a function, using return in lieu of an else statement is incredibly sloppy. Instead of:

if(A)
return
if(B)
//stuff
return
if(C)
//other stuff


you should be doing:

if(B)
//stuff
else if(C)
//other stuff


Additionally, you should be using switch() in some of these cases (look it up in the reference).


As for the issue you're having: when you save and load, your ship is not the ship that was on the map. Your ship is loaded and put into a null location, which is why you're getting a black screen when you attempt to use it again. You need to be overriding Read() and Write() to be saving the ship properly, and should be overriding mob/Del() to get rid of the ship when you log out as well.

Speaking of which: your ship should be an obj, not a mob.

Anyway, here's what a proper Read() and Write() would be:

mob/Del(var/savefile/F)
if(Ship)
del(Ship)
..()

obj/ship
Write(var/savefile/F)
..()
F["x"] << x
F["y"] << y
F["z"] << z

Read(var/savefile/F)
..()
var/tx, ty, tz
F["x"] >> tx
F["y"] >> ty
F["z"] >> tz
var/turf/T = locate(tx, ty, tz)
if(T)
loc = T


This of course would limit ships to only a single player. You would require a somewhat more sophisticated system if you wanted players to be able to share ships. Also, you should read LummoxJR's article on savefiles here.

Anyway, I think the whole thing you have right now is a mess, and needs to be reworked. I might throw something together in a bit for this, but it's rather involved and dependent on the implementation.

Also: for ship interiors, use SwapMaps, again by LummoxJR. But that's already been said.
In response to Garthor
Garthor wrote:
Speaking of which: your ship should be an obj, not a mob.

For the most part, I'm with you here (more or less) but this particular line struck me as interesting. Why, with absolute certainty, must the ship be an obj and not a mob?
In response to Geldonyetich
Because I did not think having the ship inherit the mob's Write() proc would be a good idea. If he wanted to make a mob/player and a mob/ship, then that would be okay, though a bit weird. Thinking about it now, though, it would make sense for the ship to be a mob, looking at it from the perspective of interacting with space. So, I guess the mob/player and mob/ship advice would be better. That means typecasting usr in his verbs, but oh well, it's good for his moral education.
In response to Geldonyetich
Eh, mobs and objs are mostly equivalent, except that mobs get a bit extra functionality which is player-related and person-related. A ship doesn't need any of those extras; it's not supposed to 'host' a player client, neither is it personlike, so functionality and vars like client and sight are useless for it. Most people separate inanimate objects into /obj anyway and use /mob only for persons, though sometimes they actually define things like combat properties (HP, etc) on the base /mob type, which is bad.
In response to Kaioken
Good thinking. I was looking at DM Reference today at the actual differences between mob and obj and came to much the same conclusion: it's remarkably only the things pertaining to actual player to client interaction.

Surprising considering how you'd think of a mob as being inclusive of both players and NPCs under a online-game centric definition of what a mobile is.

Lately my designs have taken to decoupling the mob/player as an actual game piece and instead as more of a piece that records disembodied player statistics and what the player should currently be able to see, and my designs have been a lot better for it. It ties into a nice problem such as Space vs Ship in that you can just shift player/mob perspective (by reassigning client.eye and setting client.perspective=EYE_PERSPECTIVE) and what their controls now influence.

Still, I can think of one issue where going through all the hassle to shoulder the additional overhead in /mob, and that's trying to avoid the caps on total /obj by shouldering some of that as /mob. I seem to recall hearing somewhere that these caps were separate.
In response to Geldonyetich
Most people actually use persons/NPCs as mobs for a good and very simple reason: you can't make make an /obj inherit from, say, /mob/fighter, and you can't make both /obj and /mob subtypes inherit from one type without bloating all of your /objs and /mobs with that type's properties at the base level, or duplicating your code - both very bad options. So you'd end up having all monsters and fightable NPCs still under /mob/fighter/NPC, because for players and monsters share properties, they have to be under the same type.
In response to Kaioken
My current approach was to have mob/player be a special disembodied mob that only governs what the player can see and things worth saving about their progress...

...then I would have something like mob/planet for mobs that engage in the kinds of activities on planets, mob/space for mobs that engage in the kinds of activities on space, ect.

This makes some sense if you have a multiple layer environment (something I've been dabbling with for awhile). The only interactions between those mobs will occur on that level, so you have separate kinds of mobs with their own kinds of statistics, and if ever they interact it will be unusual enough as to be handled through unique procs (e.g. bombing a planet from a ship).

But now that I'm looking at how the /mob type has all this bloat associated with just player connections, when the only thing that the player will ever connect to is mob/player, and am considering rolling everything that isn't a player into an obj.
In response to Geldonyetich
You could (and I'd say should) reverse that logic entirely. You'd have an obj/player which represents all the data about a player. Then, play fast and loose with client.mob, switching what we're controlling in that manner rather than through a proxy.
In response to Geldonyetich
I'm just throwing a thought, but have you also considered putting the strictly player-specific on the player type? Also known as /client.
In response to Kaioken
I was going to say that but there's a damn good reason not to:

/logs out before you can question me further
In response to Garthor
You guys are making this more difficult.
So I have some bad habits when it comes to coding, but the code I posted WORKS. I just need to figure out how to save it right, and then load it right, I do not need to be lectured on how I code my stuff. Do I appreciate your help anyways? Yes I do.

I will look into SwitchMaps, Thank you.
In response to VolksBlade
Works like a Pinto. I'd rather have a Ferrari.