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

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
}