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::    bodypart.rb
# Author:   Craig Smith

# This source code copyright (C) 2009 Craig Smith
# All rights reserved.
#
# Released under the terms of the TeensyMUD Public License
# See LICENSE file for additional information.
#

$:.unshift "lib" if !$:.include? "lib"

require 'core/gameobject'
require 'storage/properties'

# Body parts represent the pieces that make up a characters or mobiles
# body.  It conains information if it is core to the survival of the creature
# if it can be crippled as well as what can be worn on it.
#
class BodyPart < GameObject
  logger 'DEBUG'

  property :head, :tail, :core, :worn, :health, :maxhp, :crippled, :wield, :rot_ticks
  
  # Create a new BodyPart
  # This not meant to be called directly from a player but the game
  # system itself, so there are no owners.
  # [+name+]    The displayed name of the Container.
  # [+return+]  A handle to the new Container.
  def initialize(name, owner)
    super(name, owner)
    self.head = nil	# The head of the object
    self.tail = []	# If the object has any tails
    self.core = false   # If a part is core and it is destroyed the player dies
    self.worn = {}	# Hash of attribute => oid worn
    self.health = 0	# Each bodypart has it's own health value
    self.maxhp = 0
    self.crippled = false
    self.wield = nil
    self.rot_ticks = Corpse::DEFAULT_ROT_TICKS
    put_object(self)
  end

  def reset
	self.crippled = false
	self.wield = nil
	self.contents.clear
	self.rot_ticks = Corpse::DEFAULT_ROT_TICKS
	self.worn = {}
	self.maxhp = 0
  end

  # Sets the head of an object.  Example Head for an arm might be Torso
  # [+head+] Head of the body part is attached to
  # [+return+] undefined
  def setHead(head)
	if head.is_a? BodyPart
		self.head = head.id
	elsif head.is_a? Fixnum
		self.head = head
	else
		log.error("setHead recieved a non digit or bodyPart")
	end
  end

  # Adds a tail to an object.  Example Tail for a torso is Arm, Leg
  # [+tail+] Tail of a body part is attached to
  # [+return+] undefined
  def addTail(tail)
	if tail.is_a? BodyPart
		self.tail << tail.id
	elsif tail.is_a? Fixnum
		self.tail << tail
	else
		log.error("setTail recieved a non digit or bodyPart")
	end
  end

  # Puts an oid on the body parts attribute, Eg: hand, head, eyes...
  # [+oid+] Oid of the object to be worn
  # [+location+] attribute location to wear the item
  # [+return+] true on success
  def wearItem(oid, location)
	if has_attribute? location and not worn.has_key? location
		worn[location] = oid
		return true
	end	
	false
  end

  # Removes the oid worn at location and returns it
  # [+location+] The part location of worn item to remove
  # [+return+] Oid of item removed or nil if none
  def removeItem(location)
	oid = nil
	if worn.has_key? location
		oid = worn[location]
		worn.delete location
	end
	oid
  end

  # Returns an array of Oids this body part has on
  # [+return+] Array of Oids worn on this part
  def wearing
	clothes = []
	worn.each do |loc, oid|
		clothes << oid
	end
	clothes
  end

  # :describe event for body parts
  def describe(e)
	msg = ""
	msg << "(#{id}) " if get_object(e.from).get_stat(:debugmode)
	msg << "[COLOR Yellow]"
	msg << _("You see ")
	clothes = false
	weapon = false
	worn.each do |loc, oid|
		clothes = true
		obj = get_object(oid)
		msg << _("%{obj} on its %{loc}" % {:obj => obj.shortname, :loc => loc})
	end
	if wield
		obj = get_object(wield)
		msg << _("%{obj} is still in its %{loc}" % {:obj => obj.shortname, :loc => name})
		weapon = true
	end
	if not clothes and not weapon
		msg << _("a naked %{part}" % {:part => name})
	end
	msg << "[/COLOR]"
	add_event(id, e.from, :show, msg)
  end

  # Event :rot
  # [+e+] Event info
  # [+return+] Undefined
  def rot(e)
	self.rot_ticks = Corpse::DEFAULT_ROT_TICKS if not rot_ticks # Init
	return if not location
	return if location == 0
	loc = get_object(location)
	# Will only rot when in a room
	return if not loc.is_a? Room
	self.rot_ticks -= 1
	if rot_ticks < 1
		loc.say _("A horde of hungry maggots devour %{bodypart}." % {:bodypart => shortname})
		worn.each do |l, c|
			loc.add_contents(c)
			get_object(c).location = loc.id
			worn.delete(l)
		end
		if wield
			loc.add_contents(wield)
			get_object(part.wield).location = loc.id
			weild = nil
		end
		loc.delete_contents(id)
		self.unused = true
		self.location = nil
		tail.each do |tid|
			part = get_object(tid)
			part.worn.each do |l, c|
				loc.add_contents(c)
				get_object(c).location = loc.id
				part.delete(l)
			end
			if part.wield
				loc.add_contents(part.wield)
				get_object(part.wield).location = loc.id
				part.wield = nil
			end
			part.unused = true
			part.location = nil
		end
	end
  end


end