""" body.py
 Copyright (C) 1998-1999 Aloril
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
"""

import whrandom
from types import *
from copy import copy,deepcopy

from thing import thing
from vbody import vbody
import const,geometry,wtime,prob
from event import *
from mind import mind
from misc import *

class mind_events(thing):
    "process events from mind (check validity etc..)"
    def __init__(self, body):
        thing.__init__(self,name=body.name)
        self.body=body
        self.mind=body.mind
    #event handling: 
    #e is current input event
    #may return new events
    def move_event(self,e):
        e2=copy(e)
        w=e.what
        #source
        source_xyz=w.get_xyz()
        if type(source_xyz)!=TupleType:
            return [event("illegal",what=e,what_desc="source_xyz")]
        source_xyz=tuple(map(float,source_xyz))
        #target
        try:
            target_xyz=e.loc.get_xyz()
        except AttributeError:
            target_xyz=e.loc
            if type(target_xyz)!=TupleType:
                return [event("illegal",what=e,what_desc="target_xyz")]
        target_xyz=tuple(map(float,target_xyz))
        #decide how far
        if geometry.distance(source_xyz,target_xyz)>100.0:
            target=geometry.distance_from_begin(source_xyz,target_xyz,100.0)
        else:
            target=e.loc
        e2.loc=target
        if not e2.target: e2.target=e2.what
        return [e2]
    def cut_event(self,e):
        t=e.what #thing
        return [event("change",target=t,what=t,amount=-0.1)]
    def make_event(self,e):
        what=get_thing_class(e.what)
        if e.loc:
            t=apply(what,(),{"name":e.what, "desc":e.what_desc,
                             "place":e.what_desc, "xyz":e.loc,
                             "status":0.1, "age":0.0})
        else:
            t=apply(what,(),{"name":e.what, "desc":e.what_desc,
                             "place":self.body, "status":0.1})
        return [event("make", what=t)]
    def change_event(self,e):
        if not e.target: e.target=e.what
        return [e]
    def undefined_event(self,e):
        #just pass others
        return [e]

class world_events(thing):
    "process events from world to mind (filter when being in sleep or drunk)"
    #CHEAT!
    #input: no filtering currently (in future: filter when being in sleep or drunk)
    def __init__(self, body):
        thing.__init__(self,name=body.name)
        self.body=body
        self.mind=body.mind
    #event handling: 
    #e is current input event
    #may return new events
    def move_event(self,e):
        #these go through body and 
        #are handled as sight event
        pass
    def change_event(self,e):
        #see above
        pass
    def look_event(self,e):
        #ignored
        pass
    def undefined_event(self,e):
        #passed unchanged
        return [e]

class body(vbody):
    def __init__(self, **kw):
        apply(thing.__init__,(self,),kw)
        set_kw(self,kw,"sex","female")
        #additional attributes are set later
        self.mind=None
        self.wevents=world_events(self)
        self.mevents=mind_events(self)
    #event handling: 
    #e is current input event
    #may return new events
    #for others: see thing.py
    #def destroy_event(self, e):
    #    self.mevents.destroy()
    #    self.mind=None
    def run_step(self,time,input):
        """run one time step:
           feed input to mind and filter/modify output"""
        if not self.mind:
            self.mind=mind(self.id)
            input=self.look_event(event("look"))+input
        output=[]
        #random events
        #death (CHEAT!: should use some chance/time)
        #should take into account age too
        if prob.die(self.age):
            #CHEAT! : leak: add things back to world
            #should be done by world
            e=event("destroy", desc="death", what=self)
            input.append(e)
            output.append(e)
        if (prob.birth(self.age) and self.sex=="female") or \
           hasattr(self,"give_birth_now"):
            if hasattr(self,"give_birth_now"): del self.give_birth_now
            #it gives birth
            #CHEAT!: name should be given by parents!
            #do it when generally implement talk/rumors
            name=self.name+`whrandom.randint(0,9)`
            baby=ething(name,type=self.get_short_type(),
                        sex=whrandom.choice(['male','female']),
                        age=0.0,copy=self)
            e=event("make", desc="birth", what=baby)
            #input.append(e)
            output.append(e)
        body_output=self.analyse_input(input)
        input2=self.wevents.analyse_input(input+body_output)
        mind_output=self.send_events(time,input2)
        #process that output to check how legal it is
        output=output+self.mevents.analyse_input(mind_output)
        return body_output+output

    Source: geocities.com/siliconvalley/station/4279/src

               ( geocities.com/siliconvalley/station/4279)                   ( geocities.com/siliconvalley/station)                   ( geocities.com/siliconvalley)