Move object to random adjacent room.

mhoffman
I'm new to Quest but I am trying to think of a way to create a strategic 'zombie apocalypse'. Each zombie is its own object and as the player spends time with each move, each zombie will move to a random adjacent room and eventually disseminate throughout the map. This would help the gameplay to be different every time and make it more immersive than multiple scripted events. I need to have each object (zombie) move to a random adjacent room every turn.

XanMag
Are you cloning the zombies after each move and adding them to rooms or do you have a set number of zombies scattered on your map and moving that set number around?

In other words is it add a zombie after each turn and move it somewhere random? Or is it there are 10 total zombies and they all get randomly moved after each turn?

XanMag
Either way... I'd put a turn script in for each zombie. If this doesn't make sense I'll clarify with an example:

1. In the game tab add a script that runs after every turn.
2. 'Set a variable or attribute'.
3. To keep it simple, set the variable 'x' = random number between number 1 and number y (where y = # of rooms you want zombie A to move to).
4. Now, add another new script. Add an 'If' script (can be clicked at top right of box).
5. In the 'If' of this script, it should look like this --> If expression x = 1
6. For the Then part, add a move object script and move zombie A to whatever room you want.
7. Repeat steps 4-6 except change the value of x to 2.
8. Copy and paste this and change the Zombie A to Zombie B, c,d,e,f, etc...
9. You can control the zombie spawns this way too. If you want safe rooms, simply never move any zombie to that room. You only want 1 per room, give each zombie a sector that they can patrol.

WARNING!! There will be problems doing this. What do you do if your player is in a room that a zombie enters? You'll need a message to print I would think? What happens if the player wants to kill a zombie, attacks one and it disappears to another room?

I just offer this as a suggestion. Not sure if it is the best option, but it's the only one my little brain can think of. What you want to do is a lot more complicated than it sounds. Good luck!

Edit: I'm sure there's an easy way to keep a zombie in the room with the player. Something like if zombie is visible, then set variable = 0, where 0 is a blank then (zombie doesn't move).

mhoffman
This is a great idea! I'm thinking of using 100 zombies and each moves individually so this will be quite monotonous but definitely worth it. I figure I could get over that problem by having the script you described under the "If object is reachable/not reachable" rule. Then it could behave differently if the player was in the same room and I could remove the zombie1, 2, 3 etc if it was 'killed'. However this method you described would move a zombie to any room on the map relative to the zombie's location. But I suppose it makes no difference. It only would if I could find a way to have the player discern how many 'zombies' or if there even were any in a certain room by 'looking around a corner', "out the window", or "looking at a home security camera." Until I figure out if I can do that and how, this is a perfect solution! Thank you so much!

mhoffman
Actually there is another issue. If the player finds himself in a room with 15 zombies and decides to run to a different room, those fifteen zombies should be scripted to then follow the player to that room instead of randomly moving. Is it possible to have an object 'follow' the player without it being in his inventory?"

HegemonKhan
this is not simple stuff... but here's an example of how it can be done (probably not the most efficient, meh, I'm not at Pixie's, Jay's, Pertex', etc levels of coding ability, lol):

<object name="global_data_object">
</object>

<object name="room_3">
<inherit name="room_object_type" />
<attr name="x_coordinate" type="int">0</attr>
<attr name="y_coordinate" type="int">1</attr>
<attr name="z_coordinate" type="int">1</attr>
</object>

<object name="room_6">
<inherit name="room_object_type" />
<attr name="x_coordinate" type="int">2</attr>
<attr name="y_coordinate" type="int">1</attr>
<attr name="z_coordinate" type="int">1</attr>
</object>

<object name="room_9">
<inherit name="room_object_type" />
<attr name="x_coordinate" type="int">1</attr>
<attr name="y_coordinate" type="int">1</attr>
<attr name="z_coordinate" type="int">1</attr>
</object>

<object name="room_4">
<inherit name="room_object_type" />
<attr name="x_coordinate" type="int">3</attr>
<attr name="y_coordinate" type="int">2</attr>
<attr name="z_coordinate" type="int">2</attr>
</object>

<object name="room_8">
<inherit name="room_object_type" />
<attr name="x_coordinate" type="int">5</attr>
<attr name="y_coordinate" type="int">2</attr>
<attr name="z_coordinate" type="int">2</attr>
</object>

<object name="room_12">
<inherit name="room_object_type" />
<attr name="x_coordinate" type="int">4</attr>
<attr name="y_coordinate" type="int">2</attr>
<attr name="z_coordinate" type="int">2</attr>
</object>

<object name="zombie_1">
<inherit name="monster_object_type" />
<attr name="parent" type="object">room_9</attr>
<attr name="alias" type="string">zombie</attr>
<attr name="current_life" type="int">10</attr>
<attr name="maximum_life" type="int">10</attr>
<attr name="experience" type="int">2</attr>
<attr name="cash" type="int">5</attr>
<attr name="undead" type="boolean">true</attr>
<attr name="room_object_list" type="simpleobjectlist">room_3; room_6; room_9</attr>
</object>

<object name="orc_1">
<inherit name="monster_object_type" />
<attr name="parent" type="object">room_12</attr>
<attr name="alias" type="string">orc</attr>
<attr name="current_life" type="int">50</attr>
<attr name="maximum_life" type="int">50</attr>
<attr name="experience" type="int">25</attr>
<attr name="cash" type="int">10</attr>
<attr name="damage" type="int">10</attr>
<attr name="defense" type="int">5</attr>
<attr name="room_object_list" type="simpleobjectlist">room_4; room_8; room_12</attr>
</object>

<type name="monster_object_type">
<attr name="type_of_object" type="string">monster</attr>
<attr name="alias" type="string">monster</attr>
<attr name="current_life" type="int">1</attr>
<attr name="maximum_life" type="int">1</attr>
<attr name="experience" type="int">0</attr>
<attr name="cash" type="int">0</attr>
<attr name="dead" type="boolean">false</attr>
<attr name="undead" type="boolean">false</attr>
<attr name="damage" type="int">1</attr>
<attr name="defense" type="int">0</attr>
</type>

<type name="room_object_type">
<attr name="type_of_object" type="string">room</attr>
<attr name="x_coordinate" type="int">-1</attr>
<attr name="y_coordinate" type="int">-1</attr>
<attr name="z_coordinate" type="int">-1</attr>
<attr name="alias" type="string">room</attr>
</type>

<function name="room_adjacency_function" type="boolean" parameters="room_parameter">
foreach (room_variable, global_data_object.all_rooms_object_list) {
if (room_variable.x_coordinate >= room_parameter.x_coordinate - 1 and room_variable.x_coordinate <= room_parameter.x_coordinate + 1) {
return true
} else if (room_variable.y_coordinate >= room_parameter.y_coordinate - 1 and room_variable.y_coordinate <= room_parameter.y_coordinate + 1) {
return true
} else if (room_variable.z_coordinate >= room_parameter.z_coordinate - 1 and room_variable.z_coordinate <= room_parameter.z_coordinate + 1) {
return true
} else {
return false
}
}
</function>

<function name="populate_room_adjaceny_object_list_function">
if (HasAttribute (global_data_object, "room_adjaceny_object_list")) {
foreach (object_variable, global_data_object.room_adjaceny_object_list) {
list remove (global_data_object.room_adjaceny_object_list, object_variable)
}
} else {
global_data_object.room_adjaceny_object_list = NewObjectList ()
}
foreach (room_variable, global_data_object.all_rooms_object_list) {
if (room_adjacency_function (room_variable) and not ListContains (global_data_object.room_adjaceny_object_list, room_variable)) {
list add (global_data_object.room_adjaceny_object_list, room_variable)
}
}
</function>

<function name="populate_all_rooms_object_list_function">
global_data_object.all_rooms_object_list = NewObjectList ()
foreach (object_variable, AllObjects()) {
if (GetString (object_variable, "type_of_object") = "room") {
list add (global_data_object.all_rooms_object_list, object_variable)
}
}
</function>

<function name="populate_all_monsters_object_list_function">
global_data_object.all_monsters_object_list = NewObjectList ()
foreach (object_variable, AllObjects()) {
if (GetString (object_variable, "type_of_object") = "monster") {
list add (global_data_object.all_monsters_object_list, object_variable)
}
}
</function>

<function name="all_monster_movement_function">
foreach (monster_variable, global_data_object.all_monsters_object_list) {
if (not monster_variable.dead) {
removed_room = monster_variable.parent
list remove (monster_variable.room_object_list, monster_variable.parent)
monster_variable.parent = ObjectListItem (monster_variable.room_object_list, GetRandomInt (0, ListCount (monster_variable.room_object_list) - 1))
list add (monster_variable.room_object_list, removed_room)
}
}
</function>


I'm tired... someone else can take what I've done and help you with implementing it and/or explaining it...

-------

HK edit:

my logic with the adjacency-coordinate handling is wrong, as it's not quite that simple, lol. Can you see/understand why it is wrong?

HegemonKhan
Sgrieg's Following Code, an example for you:

if (not zombie.parent = player.parent) {
zombie.parent = player.parent
}


the 'parent' Object Attribute is the exact same thing as the GUI~Editor's 'MoveObject()' Script/Function

player.parent = room // the 'player' Player Object is (contained/set/moved/placed) in(within) the 'room' Room Object
~ is the same as ~
MoveObject (player, room) // the 'player' Player Object is (contained/set/moved/placed) in(within) the 'room' Room Object

gold_coins.parent = treasure_chest // the 'gold_coins' Object is (contained/set) in(within) the 'treasure_chest' Object
~ is the same as ~
MoveObject (gold_coins, treasure_chest) // the 'gold_coins' Object is (contained/set/moved/placed) in(within) the 'treasure_chest' Object

so... if...

zombie.parent = roomX
and
player.parent = roomX
then
// zombie.parent = roomX = player.parent // they're both in the same room
// zombie.parent = player.parent // they're in the same room
// roomX = roomX // true, they're in the same room

so... explaining how Sgreig's Following code works:

if (zombie isn't in the same room as the player), then (move/put/set/contain the zombie within the same room as the player)
if (not zombie.parent = player.parent) /* then */ { (zombie.parent = player.parent) }

The Pixie
I will assume you are working offline, and can edit attributes. If you are having a lot of zombies, you should either set up one and clone it, or have a zombie type.

So there are two modes for each zombie, moving at random, or following. I would therefore set up a Boolean attribute on each zombie called "zombiefollowing". Then give it a script, called "zombiemove", to handle the movement. The way I would do it is to get the exits for the room the zombie is currently in, and pick one at random.
if (this.parent = player.parent) {
// If in the same room as the player start following
this.zombiefollowing= true
}
if (this.zombiefollowing) {
// If following just go to the room the player is in
this.parent = player.parent
}
else {
// Get all exits for the current room
l = ScopeExitsForRoom(this.parent)
//pick one at random
ex = ObjectListItem(l, GetRandomInt(0, ListCount(l) - 1)
// move to its destination
this.parent = ex.to
}

Finally you will need a turn script that iterates through each zombie, and calling that script. One way would be to go though all objects and see if it has the "zombiefollowing" attribute. If it does, it is a zombie and needs to move.
foreach (o, AllObjects()) {
if (HasBoolean(o, "zombiefollowing")) {
do(o, "zombiemove")
}
}

If all that works, you can think about handling exits zombies cannot get through (locked doors, etc.).

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums