znmud-0.0.1/benchmark/
znmud-0.0.1/cmd/
znmud-0.0.1/cmd/emotes/
znmud-0.0.1/cmd/objects/
znmud-0.0.1/cmd/tiny/
znmud-0.0.1/doc/
znmud-0.0.1/farts/
znmud-0.0.1/lib/
znmud-0.0.1/lib/combat/
znmud-0.0.1/lib/core/bodytypes/
znmud-0.0.1/lib/engine/
znmud-0.0.1/lib/farts/
znmud-0.0.1/logs/
#
# file::    exit.rb
# author::  Jon A. Lambert
# version:: 2.10.0
# date::    06/27/2006
#
# Additional Contributor: Craig Smith
#
# This source code copyright (C) 2005, 2006 by Jon A. Lambert
# All rights reserved.
#
# Released under the terms of the TeensyMUD Public License
# See LICENSE file for additional information.
#
$:.unshift "lib" if !$:.include? "lib"
$:.unshift "vendor" if !$:.include? "vendor"

require 'core/gameobject'
require 'gettext'

# The Exit class is the mother of all exits.
#
class Exit < GameObject
  property :to_room, :linked_exit, :door_state, :door_name, :required_key

  include GetText
  bindtextdomain("core")

  NO_DOOR = 0
  DOOR_OPEN = 1
  DOOR_CLOSED = 2
  DOOR_LOCKED = 3

  # Create a new Exit object
  # [+name+]   The displayed name of the room
  # [+owner+]    The owner id of this room
  # [+return+] A handle to the new Room.
  def initialize(name, owner, location, to_room)
    super(name, owner, location)
    self.to_room=to_room    # The room the exit leads to
                            # location is the room the exit starts in
    self.linked_exit = nil	# Linked to another exit
    self.door_state = NO_DOOR	# Door state
    self.door_name = nil	# Name of door
    self.required_key = nil	# Key id for door
    @current_state = door_state
  end

  # Reset state of an exit
  def reset
	@current_state = door_state
  end

  # Event :opendoor
  # [+e+]      The event
  # [+return+] Undefined
  def opendoor(e)
	ch = get_object(e.from)
	loc = get_object(ch.location)
	case door_state
	when DOOR_CLOSED
		if linked_exit
			otherside = get_object(linked_exit)
			otherside.door_state = DOOR_OPEN
			get_object(to_room).say _("The %{door} opens." % {:door => door_name})
		end
		self.door_state = DOOR_OPEN
		add_event(id, ch.id, :show,  _("You open the %{door}." % {:door => door_name}))
		msg = Msg.new _("^p1 opens the %{door}." % {:door => door_name})
		msg.p1 = ch.name
    		loc.characters(ch.id).each do |p|
        		add_event(ch.id, p.id, :show, msg)
		end
	when DOOR_OPEN
		add_event(id, ch.id, :show, _("It is already open."))
	when DOOR_LOCKED
		add_event(id, ch.id, :show, _("It is locked."))
	else
		log.error ":opendoor, bad door_state"
	end
  end

  # Event :closedoor
  # [+e+]      The event
  # [+return+] Undefined
  def closedoor(e)
	ch = get_object(e.from)
	loc = get_object(ch.location)
	case door_state
	when DOOR_OPEN
		if linked_exit
			otherside = get_object(linked_exit)
			otherside.door_state = DOOR_CLOSED if not otherside.door_state == NO_DOOR
			get_object(to_room).say _("The %{door} closes shut." % {:door => door_name})
		end
		self.door_state = DOOR_CLOSED
		add_event(id, ch.id, :show,  _("You close the %{door}." % {:door => door_name}))
		msg = Msg.new _("^p1 closes the %{door}." % {:door => door_name})
		msg.p1 = ch.name
    		loc.characters(ch.id).each do |p|
        		add_event(ch.id, p.id, :show, msg)
		end
	when DOOR_CLOSED, DOOR_LOCKED
		add_event(id, ch.id, :show, _("It is already closed."))
	else
		log.error ":closedoor, bad door_state"
	end
  end

  # Event :unlockdoor
  # [+e+]      The event
  # [+return+] Undefined
  def unlockdoor(e)
	ch = get_object(e.from)
	loc = get_object(ch.location)
	case door_state
	when DOOR_LOCKED
		if required_key
			if world.can_build? ch.id
				if linked_exit
					otherside = get_object(linked_exit)
					otherside.door_state = DOOR_CLOSED if not otherside.door_state == NO_DOOR
				end
				self.door_state = DOOR_CLOSED
				add_event(id, ch.id, :show, _("You wave your hand and the %{door} unlocks." % {:door => door_name}))
				msg = Msg.new _("^p1 waves %{pos} hand and unlocks the %{door}." % {:pos => ch.pos_pronoun, :door => door_name})
				msg.p1 = ch.name
    				loc.characters(ch.id).each do |p|
		        		add_event(ch.id, p.id, :show, msg)
				end
				return
			end
			foundkey = nil
			key = get_object(required_key)
			keys = ch.find_inv(key.name)
			if keys.size > 0
				keys.each do |k|
					if k.id == key.id
						foundkey = k
					elsif key.parentid
						foundkey = k if key.parentid == key.id
					end
				end
				if foundkey
					if linked_exit
						otherside = get_object(linked_exit)
						otherside.door_state = DOOR_CLOSED if not otherside.door_state == NO_DOOR
					end
					self.door_state = DOOR_CLOSED
					add_event(id, ch.id, :show, _("You unlock the %{door} with %{key}" % {:door => door_name, :key => foundkey.shortname}))
					msg = Msg.new _("^p1 unlocks the %{door} with ^o1." % {:door => door_name})
					msg.p1 = ch.name
					msg.o1 = foundkey.shortname
    					loc.characters(ch.id).each do |p|
			        		add_event(ch.id, p.id, :show, msg)
					end
				else
					add_event(id, ch.id, :show, _("You do not have the key."))
				end
			else
				add_event(id, ch.id, :show, _("You do not have the key."))
			end
		else
			add_event(id, ch.id, :show, _("You do not have the key."))
		end	
	else
		add_event(id, ch.id, :show, _("It is not locked."))
	end
  end

  # Event :lockdoor
  # [+e+]      The event
  # [+return+] Undefined
  def lockdoor(e)
	ch = get_object(e.from)
	loc = get_object(ch.location)
	case door_state
	when DOOR_CLOSED
		if required_key
			if world.can_build? ch.id
				if linked_exit
					otherside = get_object(linked_exit)
					otherside.door_state = DOOR_LOCKED if not otherside.door_state == NO_DOOR
				end
				self.door_state = DOOR_LOCKED
				add_event(id, ch.id, :show, _("You wave your hand and the %{door} locks." % {:door => door_name}))
				msg = Msg.new _("^p1 waves %{pos} hand and locks the %{door}." % {:pos => ch.pos_pronoun, :door => door_name})
				msg.p1 = ch.name
    				loc.characters(ch.id).each do |p|
			       		add_event(ch.id, p.id, :show, msg)
				end
				return
			end
			foundkey = nil
			key = get_object(required_key)
			keys = ch.find_inv(key.name)
			if keys.size > 0
				keys.each do |k|
					if k.id == key.id
						foundkey = k
					elsif key.parentid
						foundkey = k if key.parentid == key.id
					end
				end
				if foundkey
					if linked_exit
						otherside = get_object(linked_exit)
						otherside.door_state = DOOR_LOCKED
					end
					self.door_state = DOOR_LOCKED
					add_event(id, ch.id, :show, _("You lock the %{door} with %{key}" % {:door => door_name, :key => foundkey.shortname}))
					msg = Msg.new _("^p1 locks the %{door} with ^o1." % {:door => door_name})
					msg.p1 = ch.name
					msg.o1 = foundkey.shortname
    					loc.characters(ch.id).each do |p|
			        		add_event(ch.id, p.id, :show, msg)
					end
				else
					add_event(id, ch.id, :show, _("You do not have the key."))
				end
			else
				add_event(id, ch.id, :show, _("You do not have the key."))
			end
		else # required_key
			add_event(id, ch.id, :show, _("You do not see a lock."))
		end	
	when DOOR_OPEN
		add_event(id, ch.id, :show, _("Perhaps you should shut the %{door} first." % {:door => door_name}))
	when DOOR_LOCKED
		add_event(id, ch.id, :show, _("It is already locked."))
	else
		log.error ":lockdoor, bad door_state"
	end
  end


  # Event :leave
  # [+e+]      The event
  # [+return+] Undefined
  def leave(e)
    ch = get_object(e.from)
    return if get_object(to_room).has_attribute? :no_mobile and ch.kind_of? Mobile
    if get_object(to_room).has_attribute? :peaceful and ch.has_attribute? :zombie
	add_event(ch.id, ch.id, :show, _("You are afraid to go there."))
	return
    end
    if ch.stats[:mp] < 1
    	add_event(ch.id, ch.id, :show, _("You are too exhausted!"))
	return
    end
    if door_state == DOOR_CLOSED or door_state == DOOR_LOCKED
	add_event(id, ch.id, :show, _("The %{door} is closed." % {:door =>door_name}))
	return
    end
    loc = get_object(ch.location)
    msg = Msg.new _("^p1 has left ^s1")
    msg.is_invisible = true if ch.has_attribute? :invisible
    msg.p1 = ch.name
    loc.characters(ch.id).each do |p|
        msg.s1 = e.msg if p.cansee? :dark
        add_event(ch.id, p.id, :show, msg)
    end
    # Check for followers
    if ch.followed_by
	ch.followed_by.each do |fid|
		stalker = get_object(fid)
		add_event(fid, id, :leave) if stalker.position == :standing and stalker.location == ch.location
	end
    end
    mpcost = loc.mpcost
    # remove character
    loc.delete_contents(ch.id)
    ch.location = nil
    if not world.can_build? ch.id and ch.health
	legs = ch.body.getbodyid("legs")
	feet = ch.body.getbodyid("feet")
	legs.each { |leg| mpcost += 2 if get_object(leg).crippled }
	feet.each { |foot| mpcost += 1 if get_object(foot).crippled }
	if ch.carry_weight
		ch.stats[:maxweight] = 50 if not ch.stats.has_key? :maxweight
		carry_percent =  (ch.carry_weight.to_f / ch.stats[:maxweight]) * 100
		if carry_percent > 50
			if carry_percent > 75
				mpcost += 2
			else
				mpcost += 1
			end
		end
	end
    	ch.stats[:mp] -= mpcost if mpcost > 0
    end
    add_event(id, to_room, :arrive, ch.id)
  end


end