import rxactor import rxavatar import sys import clr asm = clr.LoadAssemblyByName('OpenSim.Region.ScriptEngine.Common') Vector3 = asm.OpenSim.Region.ScriptEngine.Common.LSL_Types.Vector3 class WalkStart(rxactor.Actor): """a.k.a. TutorialMaster (controls / runs them all)""" #def __init__(self, id): # super(self.__class__, self).__init__(self, id) # self.tutorials = {} def GetScriptClassName(): return "tutorial.WalkStart" def EventCreated(self): super(self.__class__, self).EventCreated() print "tutorial.WalkStart EventCreated" self.SetUsePrimVolumeCollision(True) self.tutorials = {} self.SetTimer(0.1, True) def EventPrimVolumeCollision(self, other): if isinstance(other, rxavatar.Avatar): if not other.AgentId in self.tutorials: self.tutorials[other.AgentId] = WalkingTutorial(self, other) def EventTimer(self): try: for t in self.tutorials.itervalues(): t.update() except: print "Tutorial,EventTimer", sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2] def done(self, tut, av): del self.tutorials[av.AgentId] class WalkingGuide(rxactor.Actor): all = {} #id: instance, so that Tutorial can get the ref back GO = 1 RETURN = 2 WAIT = 3 def GetScriptClassName(): return "tutorial.Guide" def __init__(self, id): #global guides super(self.__class__, self).__init__(id) #converts id to string. ok? Guide.all[self.Id] = self #guides[id] = self #print "=>", guides print "-->", Guide.all self.tut = None #the tut where this guide is doing its part self.target = None self.state = Guide.GO def EventCreated(self): super(self.__class__, self).EventCreated() #Guide.all[self.Id] = self print "Guide created", Guide.all #self.Physics = True #self.PhysicsMode = 1 #self.Gravity = False #self.bReady = True #self.SetMesh("rabbit") #self.Activate() def go_towards(self, t, r): #is the unimplemented llTarget the same? pos = self.llGetPos() tdist = t - pos if Vector3.Mag(tdist) > r: #no worky: self.Velocity = Vector3.Norm(tdist) * 0.01 self.llSetPos(pos + (Vector3.Norm(tdist) * 0.1)) return tdist #not there yet else: #self.Velocity = Vector3(0, 0, 0) return None #reached target def update(self): if self.tut is not None: if self.target is not None: pos = self.llGetPos() avpos = self.tut.av.llGetPos() avdist = Vector3.Mag(avpos - pos) dist = -1 #failsafe for debug print if self.state == Guide.GO: if avdist < 5.0: #NOTE: int comparison failed. ironpython bug, or what? dist = self.go_towards(self.target, 0.5) if dist is None: self.state = Guide.WAIT else: self.state = Guide.RETURN self.llSay(0, "This way, just follow..") if self.state == Guide.RETURN: if avdist < 3.0: self.state = Guide.GO else: dist = self.go_towards(avpos, 4.0) if self.state == Guide.WAIT: if avdist < 2.0: self.llSay(0, "There you go - now you know how to walk. If you want to learn how to interact with things, you can proceed to the signboard nearby.") self.tut.done(self) print self.Id, Guide.all try: del Guide.all[str(self.Id)] #uh how is that int when rxActor has str()ed it? except KeyError: print "Guide.all KeyError: no,", self.Id, "in", Guide.all self.DestroyActor() #or? self.llDie() msg = "%d, %s | %s -- %s" % (self.state, str(avdist), str(dist), str(avdist)) self.llSetText(msg, Vector3(1,0,0), 1) else: print "," class WalkingTutorial: """the guiding of walking for a single user""" def __init__(self, master, av): print "starting tutorial for", av self.master = master self.av = av self.guide = None spawnloc = av.llGetPos() + Vector3(0, -2, 1) #llGetRot #REFACTOR: exceptions would be more pythonic guide_id = master.SpawnActor(spawnloc, 0, True, "tutorial.WalkingGuide") if guide_id != 0: self.guide_id = str(guide_id) #rxActor constructor str()s too :/ else: print "TUTORIAL ERROR: Failed spawning guide!" self.guide_id = None def update(self): #print "." if self.guide is None and self.guide_id is not None: if self.guide_id in Guide.all: #guides self.guide = Guide.all[self.guide_id] #guides[self.guide_id] print "Got guide", self.guide.Id, "for av", self.av.Id self.guide.tut = self self.guide.target = self.master.llGetPos() + Vector3(0, -12, 0) else: print ",", self.guide_id, " != ", Guide.all, type(self.guide_id), type(Guide.all.keys()[0]) #guides if self.guide is not None: self.guide.update() #could have own timer too - def done(self, guide): self.guide = None self.guide_id = None self.master.done(self, self.av)