You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.1 KiB
128 lines
3.1 KiB
use std::collections::HashMap;
|
|
use std::str::FromStr;
|
|
|
|
use mio::Token;
|
|
|
|
use crate::actions::look;
|
|
use crate::command::Command;
|
|
use crate::database::Db;
|
|
use crate::queue::SendQueue;
|
|
use crate::world::{Direction, Exit, Room};
|
|
use crate::{try_option_send_error, try_send_error};
|
|
|
|
/// Look at the room. Provide room name, description, and exits.
|
|
pub fn dig(command: &Command, args: String, token: Token, db: &mut Db) -> SendQueue {
|
|
let mut send_queue = SendQueue::new();
|
|
|
|
// find the player
|
|
let mut player = try_option_send_error!(token, db.get_connected_player(token));
|
|
|
|
// get the direction to dig
|
|
let direction = match Direction::from_str(&args) {
|
|
Ok(d) => d,
|
|
Err(e) => {
|
|
send_queue.push(token, format!("{}", e), true);
|
|
return send_queue;
|
|
}
|
|
};
|
|
|
|
// get starting room
|
|
let mut start_room = try_option_send_error!(token, db.load_room(player.location));
|
|
|
|
// make sure exit doesn't already exist
|
|
if start_room.exits.contains_key(&direction) {
|
|
send_queue.push(token, "Exit already exists", true);
|
|
return send_queue;
|
|
}
|
|
|
|
// get starting zone
|
|
let mut zone = try_option_send_error!(token, db.load_zone(start_room.zone));
|
|
|
|
let new_room_id = try_send_error!(token, db.new_area_id());
|
|
|
|
// create a new, empty room
|
|
let mut new_room = Room {
|
|
id: new_room_id,
|
|
zone: start_room.zone,
|
|
name: format!("New Room {}", new_room_id),
|
|
description: Vec::new(),
|
|
users_visible: true,
|
|
exits: HashMap::new(),
|
|
};
|
|
|
|
// add exit from start room to new room
|
|
let _ = start_room.exits.insert(
|
|
direction,
|
|
Exit {
|
|
target: new_room.id,
|
|
direction,
|
|
},
|
|
);
|
|
|
|
// add exit from new room to start room
|
|
let _ = new_room.exits.insert(
|
|
direction.opposite(),
|
|
Exit {
|
|
target: start_room.id,
|
|
direction: direction.opposite(),
|
|
},
|
|
);
|
|
|
|
// add new room to zone
|
|
let _ = zone.areas.insert(new_room.id);
|
|
|
|
// save the new room
|
|
if db.save_room(&new_room).is_ok() {
|
|
send_queue.push(token, "New room saved\n", false);
|
|
} else {
|
|
send_queue.push(token, "Unable to save new room", true);
|
|
return send_queue;
|
|
}
|
|
|
|
// save the start room
|
|
if db.save_room(&start_room).is_ok() {
|
|
send_queue.push(token, "Start room saved\n", false);
|
|
} else {
|
|
send_queue.push(token, "Unable to save start room", true);
|
|
return send_queue;
|
|
}
|
|
|
|
// save the zone
|
|
if db.save_zone(&zone).is_ok() {
|
|
send_queue.push(token, "Zone saved\n", false);
|
|
} else {
|
|
send_queue.push(token, "Unable to save zone", true);
|
|
return send_queue;
|
|
}
|
|
|
|
// move and save the player
|
|
player.location = new_room.id;
|
|
if db.save_player(&player).is_ok() {
|
|
if db.save_connected_player(token, &player).is_ok() {
|
|
send_queue.push(token, format!("You dig {}.\n\n", direction.long()), false);
|
|
} else {
|
|
send_queue.push(token, "Unable to save connected player", true);
|
|
}
|
|
} else {
|
|
send_queue.push(token, "Unable to save player", true);
|
|
return send_queue;
|
|
}
|
|
|
|
// inform people about what just took place
|
|
for (neighbor_token, _) in
|
|
try_send_error!(token, db.find_connected_players_by_location(start_room.id))
|
|
{
|
|
if neighbor_token != token {
|
|
send_queue.push(
|
|
neighbor_token,
|
|
format!("{} digs {}.", player.name, direction.long()),
|
|
true,
|
|
);
|
|
}
|
|
}
|
|
|
|
send_queue.append(&mut look(&command, args, token, db));
|
|
|
|
send_queue
|
|
}
|