makeclass('world') makeclass('login') makeclass('probe') makeclass('invoke') makeclass('cube') makeclass('sphere') makeclass('pylon') makeclass('roster') function pretty(t, indent, seen) indent = indent or 0 seen = seen or {} if type(t) ~= "table" then return tostring(t) end if seen[t] then return "" end seen[t] = true local spacing = string.rep(" ", indent) local out = "{\n" for k, v in pairs(t) do out = out .. spacing .. " [" .. tostring(k) .. "] = " out = out .. pretty(v, indent + 1, seen) .. ",\n" end return out .. spacing .. "}" end -- tangible.redirect(actor1,actor2) -- tangible.forcedisconnect(actor) -- tangible.keepactor(actor) -- Do not autodelete upon disconnect -- tangible.delete(actor) -- If actor is a connected player it will disconnect -- This gets called on every login except the admin user. function login.init(self, config) local player = global.get("nextplayer") global.set("nextplayer", player + 1) dprintf("login.init initializing %p, player %d", self, player) self.player = player self.color={0,0,0,0,0,0,0,0,0,0,0,0} self.kills=0 self.killed=0 tangible.animinit{tan=self, anim={bp="character", mesh="manny", plane="earth", xyz={player * 100, 0, 90}}} tangible.start(self, login.startscanning) end function login.startscanning() dprintf("Scanning started. Actor=%p Place=%p", actor, place) while true do login.onescan() wait(1) end end function login.onescan() local nearby=tangible.find{plane=tangible.animfinal(actor).plane,center=tangible.animfinal(actor).xyz,radius=1000,shape="cylinder"} for k,v in pairs(nearby) do if classname(v)=="pylon" then actor.color[v.color]=time()+30 end if classname(v)=="player" then if actor.team==v.team then for ck,cv in v.color do actor.color[ck]=math.max(actor.color[ck],cv) end else local score1=0 local score2=0 for ck,cv in actor.color do if time()-cv<0 then score1=score1+1 end end for ck,cv in v.color do if time()-cv<0 then score2=score2+1 end end if score1-score2>0 then -- kill player 2 end end end end end -- This gets called on the admin user. You can call login.init in here if you want. function world.init(self, config) dprint("world.init") global.set("nextplayer", 0) tangible.build{class=roster, anim={plane="earth", xyz={2000,0,0} } } tangible.build{class=cube, anim={plane="earth", xyz={500,-100,0}, mat_color={1,0,0}}} tangible.build{class=sphere, anim={plane="earth", xyz={500,100,0}, mat_color={0,0,1}}} login.init(self, config) end function roster.init(self,config) self.character={} end function world.buildpylon() dprint("Building pylon") local radius=1000 tangible.build{class=pylon,plane="earth",xyz={math.random(-radius,radius),math.random(-radius,radius),0}}.color=math.random(1,12) end function invoke.move(action, xyz, facing) -- todo: sanity check the parameters. tangible.animate{tan=actor, anim={action=action, interactive=true, xyz=xyz, facing=facing}} end function moveto(x, y) local z = tangible.animfinal(actor).xyz[3] tangible.animate{tan=actor, anim={action="moveto", xyz={x, y, z}, facing=math.auto}} end function login.lookmenu(add) add("Redirect", function() tangible.redirect(actor, place) end) end -- Four cases: Unnamed to new, Unnamed to existing, Named to new, Named to Existing function playas(who) dprintf("Playas %lP",place) if not actor.name and not place.character[who] then -- Unnamed to new dprintf("Case 1: Naming this character "..who) actor.name=who tangible.keepactor(actor) place.character[who]=actor elseif actor.name and not place.character[who] then -- Named to new (Hard one) dprintf("Case 2: Creating new character "..who) dprintf("Case 2.0") local nc=tangible.build{class=login, anim={plane="earth", xyz={0,0,0} } } dprintf("Case 2.1") nc.name=who dprintf("Case 2.2") tangible.keepactor(nc) dprintf("Case 2.3") place.character[who]=nc dprintf("Case 2.4: ...Place is now "..place) tangible.redirect(actor,nc) elseif not actor.name and place.character[who] then dprintf("Case 3: Logging in from unnamed to existing character "..who) tangible.redirect(actor,place.character[who]) elseif actor.name and place.character[who] then dprintf("Case 4: Logging in from "..actor.name.." to existing character "..who) tangible.redirect(actor,place.character[who]) end end function roster.lookmenu(add) for _,name in ipairs { "Albert", "Betty", "Cornelius" } do add("Play as "..name..(place.character[name] and "" or "*"), function() playas(name) end) end end function cube.lookmenu(add) add("Cube A", function () dprint("Doing Cube A") end) add("Cube B", function () dprint("Doing Cube B") end) add("Cube C", function () dprint("Doing Cube C") end) add("Cube Hi", function () dprint("Doing Cube Hi") end) add("Cube Bye", function () dprint("Doing Cube Bye") end) add("Cube Yo", function () dprint("Doing Cube Yo") end) add("Cube Z", function () dprint("Doing Cube Z") end) end function sphere.lookhotkeys(add) add("FaceL", "Sphere Hi", function () dprint("Doing Sphere Hi") end) add("FaceM", "Sphere Bye", function () dprint("Doing Sphere Bye") end) add("FaceR", "Sphere Yo", function () dprint("Doing Sphere Yo") end) end function sphere.tick(foo) dprint("Tick") end function probe.getlookat() local class = tangible.getclass(place) -- if the tangible is not of any class, return empty string. if class == nil then return "" end -- if the class has a function 'lookhotkeys', then the correct -- look-at widget is 'hotkeys'. if class.lookhotkeys ~= nil then return "hotkeys" end -- if the class has a function 'lookmenu', then the correct -- look-at widget is 'menu'. if class.lookmenu ~= nil then return "menu" end -- otherwise, if the class has a function 'getlookat', use that. if class.getlookat ~= nil then return class.getlookat() end -- by default, return the empty string. return "" end function jp3() tangible.animate{tan=actor, anim={action="play", seq="jump"}} tangible.animate{tan=actor, anim={action="play", seq="jump"}} tangible.animate{tan=actor, anim={action="play", seq="jump"}} end