29 Aug, 2013, Amore wrote in the 1st comment:
Votes: 0
Hi

I am new to programming these types of games but I know a little C++. I have a test server set up as I try to figure out how to do basic things.
my situation right now is that I am trying to make an elevator which would travel through several rooms I have created. I have been told I need to create a dynamic door to achieve this but I do not know how to go about that. Can some one please tell me step-by-step how to proceed? I know some of you might find this basic but I really don't even know how to edit an object like a door so it for example closes automatically. So when I say step-by-step I really mean it.

Thanks in advance for any help.
29 Aug, 2013, Runter wrote in the 2nd comment:
Votes: 0
There's a few ways to model this. The easiest in my view is making the elevator a room that goes up and down.

Basically you'd programmatically destroy the exits connecting the elevator to the room and then reconnect it at the next floor.

It depends on the codebase, but some it may be less than trivial to accomplish.

You'd need some type of data that associates the floor to the rooms the elevator should connect with as well. Maybe some type of array of vnums.

The other option would be making the elevator some type of vehicle that goes up and down when controls are pressed. I think this is maybe more correct but also more work.
29 Aug, 2013, Amore wrote in the 3rd comment:
Votes: 0
Ok first off, thank you for the quick reply.

Now, I like the Vehicle option you pointed out, however I cant stress enough that when I say I am new to this I really am. I have learned basics to room building and so on however I have no idea how to edit objects so that they are interactive. I'm sorry for my lack of knowlege but how would I make a room a vehicle and when you say "Some type of data that associates the floor to the rooms" I did place all the level option in the rooms in @set. If that's what you are referring to.
29 Aug, 2013, Runter wrote in the 4th comment:
Votes: 0
I don't really know enough about the codebase you're dealing with. Does it support something like elevators out of the box?

Otherwise you may have to write some code rather than build content. It may be possible to do with in game scripting depending on the codebase, or core changes may needed to be allow to the server to support it.

My original comments were regarding making core changes to the codebase.
29 Aug, 2013, Idealiad wrote in the 5th comment:
Votes: 0
Hopefully Tyche will see this thread, he probably knows the most about Cold of the folks here at MudBytes. In any case Cold does have a good scripting system so I'm guessing you can do it in-game.
29 Aug, 2013, Rarva.Riendf wrote in the 6th comment:
Votes: 0
Depeding on your pov an elevator could be one room or, the same number of room that there are floors.
In one case you make the room itself move, in the other you make the people move. (you can do that with an event trigger as en example)
I prefer to have any number of rooms that there are floors, and make them "no ground" rooms, so if people bash the door and not "flying" they fall till they reach the ground or the elevator.

And for the elevator part then I am pretty sure you find code on the net, it is a classic student assignement (not the easiest one indeed : http://www.tested.com/science/math/45188...)
29 Aug, 2013, Nathan wrote in the 7th comment:
Votes: 0
One approach I recall using on a MUCK (not this codebase, mind you) was locked exits that depended on some kind of property. On the outside, you could use the exit if the elevator was "at" that floor. The inside either had an exit that linked/unlinked programmatically or a bunch of exits that were only usable or visible if you were at the floor they went to. Of course, you could just leave all the exits possible and not worry about where the elevator is. Depends on whether or not the "travel time" or ability to access/use the elevator (i.e. if "the power is off" kind of things) figures into gameplay or if it is just there for flavor text. I suppose if you had some kind of special multi-target exit that would be useful for this. I built a subway on that same game (the first bit) once that had a vehicle (used the player's ability to @force it to move to keep it going in a somewhat autonomous fashion). Of course, they were just OOC construction for fun.
29 Aug, 2013, Scandum wrote in the 8th comment:
Votes: 0
What is a dynamic door?

You've got two options, you add proper support to create an elevator or you rig something together.

You might be able to code the elevator as an object. Next you could make it so you can't enter a room that is occupied by an object that is of similar size. You could define a cubic shape to objects, and allow things to be placed inside objects, and for a door to be installed in one of the sides of the object. Lifting up the elevator would require a rope, so you would have to add support for hanging objects.

Some parts can be scripted, like opening the doors and lowering and raising the elevator. You could also give the elevator an evil streak and let it try to kill players if the chance presents itself. Oxygen could run out in the case the elevator gets stuck and the doors remain closed, people can be crushed if they're in the room below the elevator, and people might die if the rope snaps and the elevator falls down multiple rooms.
30 Aug, 2013, Runter wrote in the 9th comment:
Votes: 0
In my view, I can't imagine many games needing to faithfully implement an elevator. I have to think about the type of mechanic I want to achieve by adding elevators.

There very well may be a legitimate case, but in general, just as a mode of transportation in a multi story structure they're generally inferior in every way to a staircase on a mud. Which is pretty strange and defeats the purpose of the item being made realistic.

The only way they start to make sense is if you have crazy high buildings, or you decide to make it so players get tired and can't climb effectively cost free.

Without these other real life gameplay elements added the benefits of an elevator are muted. And frankly, I don't think building mechanics just to satisfy real life scenarios is very good.

If the elevator is to fit a style I would much rather see it working so that you press the button, you just end up on the floor. Many games implement lifts these ways. And you'll find that most lifts that actually work in a realistic way, are always immediately available to the player–And the time spent in the lift is alway direct. None of the annoyances of real life lifts. Also, often used only as a place for some type of story to unfold. Discussions to happen, or a device to let the player see something outside of the lift before reaching the destination.

In general, what I'm trying to say is, if you're implementing it for fun or know a specific mechanic that you're trying to achieve then great. But most muds it wouldn't fit with very well as you make it very realistic to how a real lift works.
30 Aug, 2013, KaVir wrote in the 10th comment:
Votes: 0
I created an elevator for my old mud, as best as I can recall it worked like this:

The elevator was a room containing a portal (an object which you could 'enter' to travel to another room). You could change floor by speaking the floor number you wanted out loud: it would then send an appropriate message about the elevator moving, and change the portal to the room on the appropriate floor. The portals were two-way, you could only walk through them if the room on the other end also contained a portal which pointed back to your room - otherwise they were described as being closed.

By changing the cosmetics the exact same system could also be used for a train, a ferry, a bus, a time machine, and so on.
03 Sep, 2013, Tyche wrote in the 11th comment:
Votes: 0
Amore said:
Hi

I am new to programming these types of games but I know a little C++. I have a test server set up as I try to figure out how to do basic things.
my situation right now is that I am trying to make an elevator which would travel through several rooms I have created. I have been told I need to create a dynamic door to achieve this but I do not know how to go about that. Can some one please tell me step-by-step how to proceed? I know some of you might find this basic but I really don't even know how to edit an object like a door so it for example closes automatically. So when I say step-by-step I really mean it.

Thanks in advance for any help.


It's good you know a little C++, because if you knew a lot of C++ it might well screw you up understanding ColdC. ;-P
The Cold core comes with a lot of mud architecture built with ColdC.

The default $path object responds to @unlock, @lock, open, and close commands, and those have messages associated with them. What I would do is create one way paths from each level to an elevator $place, and create a one way $path from the elevator $place to any one of the levels. Then you need to remove/change the commands and messages from the $paths and add commands and messages common to an elevator. Or better yet create a new kind of $path object that you can reuse every time you need a path to an elevator or path from an elevator to a level.

For instance, the paths leading to an elevator should not be immediately openable or closeable. You might have a 'press' command which signals the elevator a desire to open the doors (or maybe accepts 'up' or 'down' if you get fancy). That should send a message to the elevator $place starting it up, the elevator place will either immediately open the doors or there will be a delay as the elevator moves down.

The elevator $path will need a press command that accepts numbers or letters to everywhere it could go plus an open or close buttons.

The elevator $place itself will need a method to process commands, and a method to run them.
It would also need an ordered list of $places it can visit, it's current location, and a queue/list of commands it's executing. Again it would be better to create a generic $elevator object that inherits $place, so you can create reuse many of them.

Some hints.

$places and $paths objects needed:

$place_level_1 -> $path_level_1_to_lift -> $place_elevator
$place_level_2 -> $path_level_2_to_lift -> $place_elevator
$place_level_3 -> $path_level_3_to_lift -> $place_elevator
$place_elevator -> $path_to_levels -> set to either $place_level_1 or $place_level_2 or $place_level_3

object $elevator parents $path; 
var $elevator current_location = $place_level_1;
var $elevator command_queue = [];
var $elevator destinations = [$place_level_1, $place_level_2, $place_level_3 ];


$path_level_1_to_lift
.press_cmd()
$elevator.command($place_level_1,'open)

$elevator
.command()
arg place, command
if (current_location == place)
.open_path(sender(), $elevator, place);
else {
command_queue = .add(command_queue,
$path_level_1_to_lift
.press_cmd()
$elevator.command($place_level_1,'open)

$elevator
.command()
arg place, command
if (current_location == place)
.open_path(sender(), $elevator, place);
else {
command_queue = .add(command_queue, [place, command}
$scheduler.add_task(5,'run_lift); // schedule task
}

.run_lift()
// move lift
// current_location = next in destinations list;

// check to see if destination on command_queue matches current location
// then open doors and delete command from queue

// if not reschedule task or if commands are still on queue
$scheduler.add_task(5,'run_lift);
[/code]

Sorry this is off the top of my head and I haven't used Cold core in a while
but I hope this gives you some ideas.

BTW, this IS a great mud coding quiz question. :-)
05 Sep, 2013, Quasar wrote in the 12th comment:
Votes: 0
Yet another ColdC example. Only needs a single object (the elevator room/car). Works only with $exit as the default exit rather than $path.

;var p, new; if(!(| valid($elevator) |)) { new = $place.spawn(); new.set_objname('elevator);}
;|as $elevator<$root>;manager = $quasar;
;|as $elevator<$root>;flags = ['variables, 'methods, 'code, 'core, 'fertile];
;|as $elevator<$root>;created_on = 1363940577;
;|as $elevator<$root>;inited = 1;
@av $elevator,task_id = -1
;|as $elevator<$elevator>;task_id = -1;
@av $elevator,lift_hints = #[]
;|as $elevator<$elevator>;lift_hints = #[];
@av $elevator,stop_queue = []
;|as $elevator<$elevator>;stop_queue = [];
;|as $elevator<$dmi_data>;descriptions = #[];
;|as $elevator<$has_commands>;shortcuts = #[];
;|as $elevator<$has_commands>;remote = #[["@reset", [["@reset", "*", "@reset <this>", 'reset_cmd, #[[1, ['this, []]]]]]]];
;|as $elevator<$has_commands>;local = #[["dest?ination", [["dest?ination", "*", "dest?ination <any>", 'dest_cmd, #[[1, ['any, []]]]]]], ["@set-lift-hint|@slh|@lift-hint", [["@set-lift-hint|@slh|@lift-hint", "* to|is *", "@set-lift-hint|@slh|@lift-hint <any> to|is <any>", 'set_lift_hint_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]]];
;|as $elevator<$has_name>;name = ['prop, "Generic Elevator", "Generic Elevator"];
;|as $elevator<$described>;prose = [];
;|as $elevator<$location>;contents = [];
;|as $elevator<$place>;entrances = [];
;|as $elevator<$place>;exits = [];
;|as $elevator<$place>;realm = $realm_of_creation;
;|as $elevator<$command_cache>;commands = #[["dest", [["dest?ination", $elevator]]], ["desti", [["dest?ination", $elevator]]], ["destin", [["dest?ination", $elevator]]], ["destina", [["dest?ination", $elevator]]], ["destinat", [["dest?ination", $elevator]]], ["destinati", [["dest?ination", $elevator]]], ["destinatio", [["dest?ination", $elevator]]], ["destination", [["dest?ination", $elevator]]], ["@set-lift-hint", [["@set-lift-hint|@slh|@lift-hint", $elevator]]], ["@slh", [["@set-lift-hint|@slh|@lift-hint", $elevator]]], ["@lift-hint", [["@set-lift-hint|@slh|@lift-hint", $elevator]]]];
;|as $elevator<$command_cache>;shortcuts = [];
;|as $elevator<$command_cache>;modules = [];
@program $elevator.reset_cmd() +access=pub
arg cmdstr, cmd, what;
var out, tmp;

// Kill any travel task
(| $scheduler.del_task(task_id) |);

// Reset the queue and task_id
stop_queue = [];
task_id = 0;

// Validate the exit out
out = (| (.exits())[1] |);
if (!out || !valid(out) || !out.is($exit))
return ">> The exit leading of the lift is either missing or bad. You need to recreate it.";
tmp = (| (.entrances())[1] |);
if (!tmp || !valid(tmp) || !tmp.is($exit)) {
user().tell(">> This elevator doesn't seem to have any valid entrances. Skipping this step.");
} else {
// Link the exit to the first room in the entrances list
(> out.relink(tmp.source()) <);

// Reset the lock
(> out.set_lock((<$true_lock_frob, #[]>)) <);
}
return ">> Your lift has been reset. Have a nice day!";

.

@program $elevator.lift_dest() +access=pub
return (> (.exits())[1].dest() <);

.

@program $elevator.prose() +access=pub
arg @no_default;
var ret;

ret = [pass(@no_default)];

// This next bit prevents the destinations stuff from being added to the room desc when you are trying to edit the actual room desc.
if (caller() != $described)
ret = [@ret, "", .dests()];
return ret;
.

@program $elevator.dests() +access=pub
var x, ways, out, d;

// Returns a formatted list of destinations for appending to the room description.
// TODO: could this maybe be converted into a generator instead?
if (!(ways = .entrances()))
return "[This lift is not connected to anything]";
out = [];
for x in [1 .. listlen(ways)] {
d = (| lift_hints[ways[x]].to_english(",") |) || "";
out = [@out, (ways[x].source() == .lift_dest() ? ">" : " ") + tostr(x).right(2) + " " + ways[x].source().name().left(20).ansi("c") + ": " + d];
}
out = [@out, "", "Use \"dest?ination <# or name>\" to make a selection"];
return out;

.


@program $elevator.dest_cmd() +access=pub
arg cmdstr, cmd, str;
var o, e;

// Save so we only have to call .entrances() once
e = .entrances();
o = .match_destination(str);
if (!o || !valid(o))
return "No such destination.";
if (o.source() == .lift_dest())
return "The computer says, \"The lift is already there.\"";
.announce(user().name() + " (to computer) says, \"" + o.source().name() + "\".");
(> .queue_stop(o) <);
.


@program $elevator.queue_stop() +access=pub
arg dest;

if (!(dest in stop_queue || []))
stop_queue = [@stop_queue || [], dest];
if (!(task_id in tasks()))
$scheduler.add_task(1, 'travel_task);
.


@program $elevator.match_destination() +access=pub
arg str;
var obj, found, i;

if (str.is_numeric()) {
i = toint(str);
if (i > 0 && i <= listlen(.entrances()))
return (.entrances())[i];
else
return 0;
}
found = [];
for obj in (.entrances()) {
if (obj.source().match_name(str))
found += [obj];
if (!found && .match_lift_hint(obj, str))
found += [obj];
}
if (listlen(found) == 1)
return found[1];
return 0;
.


@program $elevator.match_lift_hint() +access=pub
arg ele, str;
var m, a, hints;

if (!str)
return 0;
hints = (| lift_hints[ele] |) || [];
if (!hints)
return 0;
for a in (hints || []) {
if ((m = match_begin(a, str)))
return m;
}
return 0;
.


@program $elevator.parse_lift_hints() +access=pub
arg value, @args;
var objs, o;

objs = [];
for o in (value.explode(",")) {
o = o.trim();
if (o)
objs = setadd(objs, o);
}
return objs;
.


@program $elevator.set_lift_hints() +access=pub
arg name, definer, value, @args;

set_var('lift_hints, value);
.


@program $elevator.set_lift_hint_cmd() +access=pub
arg cmstr, cmd, this, prep, iobjstr;
var target, out, line, x;

target = .match_destination(this);
if (!target)
return ">> No such destination.";
if (!iobjstr)
return ">> You must give at least one argument.";
out = [];
for x in (iobjstr.explode(","))
out = [@out, x.trim()];
if (!out)
return ">> I couldn't parse any destinations from what you gave me.";
(> (lift_hints = dict_add(lift_hints || #[], target, out)) <);
return ">> You set the lift hints for " + target.namef('xref) + " to: " + out.join(",") + ".";
.


@program $elevator.lift_hints() +access=pub
return lift_hints || #[];
.


@program $elevator.travel_task() +access=pub
var tmp, out, wdelay, sdelay;

out = (> (.exits())[1] <);
if (!out || !out.is($exit))
throw(~etype, "Object is not an $exit.");
task_id = task_id();
sdelay = 5;
wdelay = 5;
while (stop_queue != []) {
.announce("The doors slide shut and the lift begins to move.");
tmp = stop_queue[1];
out.dest().announce("The lift doors slide shut.");
out.set_lock((<$false_lock_frob, #[]>));
$scheduler.sleep(wdelay);
if (stop_queue.length() == 1)
stop_queue = [];
else
stop_queue = stop_queue.subrange(2);
$scheduler.sleep(sdelay);
tmp.source().announce("The lift has arrived on this level.");
.announce("The lift comes to a stop and the doors slide open at " + tmp.source().name() + ".");
(> out.relink(tmp.source()) <);
(> out.set_lock((<$true_lock_frob, #[]>)) <);
if (stop_queue != [])
$scheduler.sleep(5);
}
.


@program $elevator.initialize_elevator() +access=pub
stop_queue = [];
task_id = -1;
lift_hints = #[];
.


@program $elevator.acceptable() +access=pub
arg actor, mover, room;

// Allow the destination to deny the move.
if (.lift_dest() != room) {
actor.tell("You call the lift.");
actor.location().announce(tostr(actor.name() + " calls the lift."), actor);
.queue_stop(mover);
return 0;
}
return 1;
.
06 Sep, 2013, Oliver wrote in the 13th comment:
Votes: 0
Out of curiosity…

Why has no one suggested using one room with one exit?

All you have to do is redefine the room referenced by the exit object. You don't even really need to deal with memory management or dynamic creation/destruction.

Elevator goes up, the exit becomes linked to room X. Elevator goes down, linked to room Y. A couple flavor echoes and this is a much easier solution than creating and destroying rooms on the fly.

KaVir suggested a similar approach, but you don't even need to mess around with portal-type objects unless your game is utilizing a coordinate system.
06 Sep, 2013, KaVir wrote in the 14th comment:
Votes: 0
Oliver said:
KaVir suggested a similar approach, but you don't even need to mess around with portal-type objects unless your game is utilizing a coordinate system.

The implementation I mentioned wasn't for a coordinate-based mud. Redefining exits is a possibility, but it's not as simple as you suggest. If you just remove the exit from the old floor then there'd be no closed door indicating that an elevator even exists - and if you're using OLC, you'd also need to keep the floor changing separated from regular building work.
06 Sep, 2013, Oliver wrote in the 15th comment:
Votes: 0
KaVir said:
Oliver said:
KaVir suggested a similar approach, but you don't even need to mess around with portal-type objects unless your game is utilizing a coordinate system.

The implementation I mentioned wasn't for a coordinate-based mud. Redefining exits is a possibility, but it's not as simple as you suggest. If you just remove the exit from the old floor then there'd be no closed door indicating that an elevator even exists - and if you're using OLC, you'd also need to keep the floor changing separated from regular building work.


I was thinking something more along the lines of this:

Room X is the elevator room.
Room Y has an exit into room X.
Room Z has an exit into room X.
Room X has one exit that switches between room Y and room Z.

Obviously, the door to room X shouldn't open from room Y if the elevator is on floor Z.

On a ROM codebase, for instance, this only involves redefining the "vnum" integer and to_room pointer of the exit object in room X. I was assuming that this would be a function incorporated into OLC, also. An exit flag, perhaps, that allows two different rooms to be specified.
0.0/15