diff options
| author | Alexander Pickering <alex@cogarr.net> | 2019-01-27 10:32:09 -0500 |
|---|---|---|
| committer | Alexander Pickering <alex@cogarr.net> | 2019-01-27 10:32:09 -0500 |
| commit | 0aae46ecc38005236210f7e243f02cac39ab1dc3 (patch) | |
| tree | e2fcc9893df4ff03a87e113b3c0ff89357c86ef7 /client/data | |
| download | home_text_adventure-0aae46ecc38005236210f7e243f02cac39ab1dc3.tar.gz home_text_adventure-0aae46ecc38005236210f7e243f02cac39ab1dc3.tar.bz2 home_text_adventure-0aae46ecc38005236210f7e243f02cac39ab1dc3.zip | |
Inital commit
Diffstat (limited to 'client/data')
27 files changed, 1654 insertions, 0 deletions
diff --git a/client/data/commands.lua b/client/data/commands.lua new file mode 100644 index 0000000..e9df205 --- /dev/null +++ b/client/data/commands.lua @@ -0,0 +1,426 @@ +local cmds = {} +local lp = require("localplayer") +local world = require("world") +local net = require("net") +local save = require("save") +local house = require("house") +function cmds.hints() end --A method to detour for palces to give hints + +local dont_hint = false +cmds.look_hint = function(...) + return {""} --We can always look +end +cmds.look = function(...) + cls() + if lp.location.is_location then + out(lp.location:get_desc()) + else + out(lp.location:get_room_desc()) + end +end +cmds.go = function(direction) + local input = string.lower(direction) + print("got input to go",input) + set_hints(unpack(world.basic_commands)) + lp:go(direction) + --local direction = +end +cmds.go_hint = function(...) + local loc = lp.location + local directions = {} + if loc.go then + for k,v in pairs(loc.go) do + directions[#directions + 1] = v[1] + end + end + return directions +end +cmds.goto_hint = function(tbl) + --print("Getting goto hint") + --print("Got loc:", loc) + local places = {} + if lp.location.is_location then + for k,v in pairs(lp.location.go) do + places[#places + 1] = v[2]().name + end + for k,v in pairs(lp.location.last_houses) do + places[#places + 1] = v + end + end + return places +end +cmds.goto = function(...) + local place_name = table.concat({...}," ") + local pns = string.lower(place_name) + print("Place name:",place_name) + local loc = lp.location + local found_place + for k,v in pairs(lp.location.go) do + if string.lower(v[2]().name) == pns then + found_place = v[2]() + print("Found place location!",found_place.name) + break + end + end + if found_place == nil then --We haven't found what they're looking for yet + print("Did not find place name, looking further") + if net.house_exists(loc.name,place_name) then + print("Found place!",loc.name,place_name) + local place = net.get_house(loc.name,place_name) + print("Place was:",place) + found_place = place + end + end + if found_place == nil then + print("Places:") + for k,v in pairs(loc.go) do + print(k,":",v) + end + fail_hint("Could not find a place:", place_name) + return + end + print("found_place is location:",found_place.is_location) + if found_place.is_location then + print("Using lp.goto_location",found_place.name) + lp:goto_location(found_place) + elseif found_place ~= nil then + print("Using lp:goto_house") + lp:goto_house(loc.name,place_name) + end + print("Found place was",found_place) + --lp:goto_location(found_place) +end +cmds.settle = function(...) + local oldruncommand = run_command + cls() + out("Enter a name for your house:") + set_hints("") + dont_hint = true + command_over = function(text) + print("Got text:",text) + if net.is_name_available(text, lp.location.name) then + local nhouse = house.create_new(text) + local house_data = save.table_to_string(nhouse) + print("Made house:",house_data) + net.claim_house(lp.location.name,text,lp.id) + net.write_house(lp.id,house_data) + command_over = nil + clear_cmdbox() + cls() + out(lp.location.settle_txt) + + dont_hint=false + else + fail_hint("That name is already taken! Try another!") + end + end + world.basic_commands[#world.basic_commands] = nil +end +cmds.settle_hint = function(...) + if lp.has_settled then + return {"You have already setteled!"} + else + return {"Once you settle an area, you cannot settle again!"} + end +end +cmds.test = function(...) + lp:goto_house("City/one") +end +cmds.test_hint = function(...) + +end +local valid_directions = { + north = true, south = true, east = true, west = true, up = true, down = true +} +cmds.create_room = function(direction, ...) + local name = table.concat({...}," ") + print("create_room called with", direction,name) + if not direction and name then + fail_hint("To create a room, give it a direction (north, east, up, ect.) and a name") + end + direction = string.lower(direction) + if not lp.in_house then + fail_hint("You must be in your house to create a room!") + return + end + if not valid_directions[direction] then + fail_hint("You can't make a room \"" .. direction .. "\". Use north, east, up, ect.") + return + end + local cur_house = lp.in_house + local cur_room = lp.location + --print("cur_house is", cur_house) + if cur_house:has_room_in_direction(cur_room,direction) then + cls() + out([[ +There is already a room in this direction, would you like make a doorway to +this room instead? (yes/no) +]]) + dont_hint = true + command_over = function(text) + clear_cmdbox() + if text == "yes" then + cur_house:create_doorway(cur_room,direction) + cls() + out("You created a doorway") + else + cls() + out("You don't do anything") + end + command_over = nil + dont_hint = false + + end + else + cur_house:create_room(cur_room,direction,name) + cls() + out("You create a new room " .. direction) + end + + --cur_house:create_room(cur_house,direction,name) +end +cmds.create_room_hint = function(...) + return {"create_room <direction> <room_name>"} +end + +cmds.edit_room = function(field) + if field == "description" then + enable_multibox(true) + multibox:settext(lp.location.desc) + --set_editbox_multi(true) + multibox_donebut.onClick = function(self) + print("over multibut click") + local toset = multibox:gettext() + print("Setting text to ", toset) + lp.location.desc = toset + cls() + out(lp.location:get_room_desc()) + enable_multibox(false) + --set_editbox_multi(false) + end + elseif field == "name" then + cls() + out("Enter the new room name") + dont_hint = true + command_over = function(text) + print("Overrideing command") + lp.location.name = text + clear_cmdbox() + cls() + out("You set the room's name to " .. text) + command_over = nil + dont_hint = false + end + end + +end +cmds.edit_room_hint = function(...) + return {"edit_room (name|description)"} +end + +cmds.create_item = function(...) + local itemname = table.concat({...}," ") + dont_hint = true + cls() + out("Describe the location of the item in the room") + command_over = function(text) + cls() + out("Enter a description for this item") + local item_loc = text + enable_multibox(true) + multibox_donebut.onClick = function(self) + local description = multibox:gettext() + print("Creating an item in", lp.location.name) + lp.location:add_item(itemname,description,item_loc) + cls() + out(lp.location:get_room_desc()) + enable_multibox(false) + end + clear_cmdbox() + command_over = nil + dont_hint = false + end +end + +cmds.create_item_hint = function(...) + return {"create_item item_name"} +end + +cmds.edit_item = function(field,...) + local itemname = table.concat({...}," ") + local this_item + if lp.location.items == nil then + fail_hint("You can only edit items in a house") + return + end + for itemnum,item in pairs(lp.location.items) do + if item.name == itemname then + this_item = item + break + end + end + if this_item == nil then + fail_hint("Could not find an item named " .. itemname) + return + end + if field == "name" then + cls() + out("Enter a new name") + dont_hint = true + command_over = function(text) + this_item.name = text + command_over = nil + clear_cmdbox() + out(lp.location:get_room_desc()) + dont_hint = false + end + elseif field == "description" then + cls() + enable_multibox(true) + multibox:settext(this_item.desc) + multibox_donebut.onClick = function(self) + local newdesc = multibox:gettext() + this_item.desc = newdesc + cls() + out(lp.location:get_room_desc()) + enable_multibox(false) + end + elseif field == "location" then + cls() + out("Enter a new location") + dont_hint = true + command_over = function(text) + this_item.location = text + command_over = nil + clear_cmdbox() + out(lp.location:get_room_desc()) + dont_hint = false + end + + else + fail_hint("Could not edit an item's \"" .. field .. "\".") + end +end + +cmds.edit_item_hint = function(...) + return {"edit_item (name|description|location) item_name"} +end + +cmds.examine = function(...) + local item_name = table.concat({...}," ") + if lp.location.items then + local item_found = false + cls() + for k,item in pairs(lp.location.items) do + if item.name == item_name then + out(item.desc) + item_found = true + end + end + if not item_found then + fail_hint("You couldn't find a " .. item_name .. " to examine") + end + else + fail_hint("You couldn't find anything to examine") + end +end + +cmds.examine_hint = function(...) + local itemlist = {} + for k,item in pairs(lp.location.items) do + itemlist[#itemlist + 1] = item.name + end + return itemlist +end + +cmds.save = function(...) + print("in_house:",lp.in_house) + print("owns:",lp.owns) + if (not lp.in_house) or (not lp.owns) then + fail_hint("You can only save when you're in your house.") + return + end + --lp.in_house["in"] = nil + local housedata = save.table_to_string(lp.in_house) + net.write_house(lp.id,housedata) + cls() + out("House saved!") + print("House data is", housedata) +end +cmds.save_hint = function(...) + return {"Save your house!"} +end + +cmds.destroy_room = function(direction) + direction = string.lower(direction) + if not lp.in_house or not lp.owns then + fail_hint("You can only destory rooms in your own house.") + return + end + lp.in_house:destroy_room(lp.location,direction) + cls() + out(lp.location:get_room_desc()) + print("Room destroyed!") +end + +cmds.destroy_room_hint = function(...) + return {"destroy_room <direction>"} +end + +add_cmdbox_hook(function(cmdbox) + local text = cmdbox:gettext() + if text == "go south" and (not lp.location.is_location) and (lp.location.south == "exit") and (lp.owns) then + set_hints("Don't forget to save before exiting your house!") + end +end) + +add_cmdbox_hook(function(cmdbox) + if dont_hint then return end + local text = cmdbox:gettext() + if string.find(text,".* $") then + local root = string.match(text,"^([^%s]+)") + print("root is:") + if cmds[root] then + local hints = cmds[root .. "_hint"]() + assert(type(hints) == "table","Tried to set hints not a table!") + for k,v in pairs(hints) do + assertf(type(v) == "string","Hints table has something other than a string: %s",type(v)) + end + set_hints(unpack(hints)) + end + elseif string.find(text,"^[^%s]*$") then --Does not have a root command yet + local cmd_set = {} + for k,v in pairs(world.basic_commands) do + cmd_set[k] = v + end + if lp.owns and lp.in_house then + print("We own this place, adding extra commands") + cmd_set[#cmd_set + 1] = "create_room" + cmd_set[#cmd_set + 1] = "edit_room" + cmd_set[#cmd_set + 1] = "destroy_room" + + cmd_set[#cmd_set + 1] = "create_item" + cmd_set[#cmd_set + 1] = "edit_item" + cmd_set[#cmd_set + 1] = "destroy_item" + + cmd_set[#cmd_set + 1] = "save" + end + if not lp.location.is_location and lp.location.items then + cmd_set[#cmd_set + 1] = "examine" + else + cmd_set[#cmd_set + 1] = "goto" + end + set_hints(unpack(cmd_set)) + else + local root = string.match(text,"^([^%s]+)%s.+") + print("root is:") + if cmds[root] then + local hints = cmds[root .. "_hint"]() + assert(type(hints) == "table","Tried to set hints not a table!") + set_hints(unpack(hints)) + end + + end +end) + +return cmds diff --git a/client/data/deviceinit.lua b/client/data/deviceinit.lua new file mode 100644 index 0000000..ed47a27 --- /dev/null +++ b/client/data/deviceinit.lua @@ -0,0 +1,92 @@ +print("device init called") +return { + --[[ + Anti-Alias + Should the window use fullscreen anti aliasing + Default:16 + ]] + ["Anti Alias"] = 16, + --[[ + Bits Per Pixel + The minimum bits per pixel of the color buffer in fullscreen. Ignored in window mode. + Default:16 + ]] + ["Bits Per Pixel"] = 16, + --[[ + Device Type + Options: + WIN32 - Only avaliable on windows desktops + WINCE - Only avaliable on windows mobile + COCOA - Only avaliable on OSX + X11 - Avaliable on Linux, Solaris, BSD, anyone that uses X11 + SDL - Avaliable on most systems + CONSOLE - Usually avaliable, but can only render text + BEST - Automatically choose the best device. + Default:Best + ]] + ["Device Type"] = "BEST", + --[[ + Display Adapter + Pick which graphics card is used for rendering when there is more than one. + Default:0 + ]] + ["Display Adapter"] = 0, + --[[ + Double Buffer + Should the window use doublebuffering? + Default:false + ]] + ["Double Buffer"] = true, + --[[ + Multithreaded + Should the display use multiple threads? + Default:false + ]] + ["Multithreaded"] = false, + --[[ + Driver Type + The video driver used to render graphics + Options: + NULL - You probably don't want this one + SOFTWARE - Donate your computer to a mueseum + BURNINGS - a software alternative + D3D8 - Direct 3D 8 Win32 only + D3D9 - Direct 3D 9 Win32 only + OPENGL - Open GL + (vulkan support comming soon... maybe.) + Default:OPENGL + ]] + ["Driver Type"] = "OPENGL", + --[[ + Fullscreen + Should the window be fullscreen? + Default:false + ]] + ["Fullscreen"] = false, + --[[ + Stencil buffer + Should the stencil buffer be enabled? + Default:false + ]] + ["Stencil Buffer"] = true, + --[[ + Stereo Buffer + Should the window use stereo buffers? + Default:false + ]] + ["Stereo Buffer"] = false, + --[[ + Vertical Sync + Should the frame wait to be displayed to screen before starting the next draw? + Enable this if you are getting graphical artifacts + Default:false + ]] + ["VSync"] = true, + --[[ + Window Width/height + Adjusts the size of the window. + Default: 640,480 + ]] + ["Window Width"] = 80 * 10, + ["Window Height"] = 640, +} diff --git a/client/data/fn.lua b/client/data/fn.lua new file mode 100644 index 0000000..e2fa59e --- /dev/null +++ b/client/data/fn.lua @@ -0,0 +1,120 @@ +--[[ +Functional programming primitives that are occasionally useful + +This is not a complete set of primitives, I make them when I need them. Anywhere I use these +heavily (where someone unfamiliar with the functional paradigm might get confused) +I have tried to add comments above or below explaining what it does. +]] +local fn = {} + +--Returns a function that "stores" the arguments this function was called with +--For example +--[[ +local hiprint = fn.curry(print,"[hi]") +hiprint("world") -- calls print("[hi]","world"), prints "[hi] world" +]] +function fn.curry(func,...) + local args = {...} + return function(...) + local nargs = {} + for k,v in pairs(args) do nargs[k] = v end + for k,v in pairs({...}) do + nargs[#nargs + 1] = v + end + func(table.unpack(nargs)) + end +end + +--Returns a function that calls all functions starting with the rightmost function +--and calling the "next" function with the returns of the previous function. +--The first function can be called with any arguments like normal +--Anything returned from the last function is returned "out" of this function. +--Example: +-- +--local fn = require("fn") +--local printf = fn.compose(print,string.format) +--printf("This is %s shit","funky") --prints "This is some funky shit" +function fn.compose(...) + local nargs = {...} + local lastresult + return function(...) + lastresult = {...} + for n = #nargs, 1, -1 do + lastresult = {nargs[n](table.unpack(lastresult))} + end + return table.unpack(lastresult) + end +end + +--Returns a function that applies the given function on a table called with it. +--Example: +-- +--local fn = require("fn") +--local add_five = fn.map(function(e) return e + 5 end) +--add_five({1,4,9}) --Returns a table {6,10,14} +function fn.map(func) + return function(tbl) + local ret = {} + for k,v in pairs(tbl) do + ret[k] = func(v) + end + return ret + end +end + +--Returns a function that removes anything NOT matching the given function +--Example: +-- +--local fn = require("fn") +--local important_skills = fn.filter(function(e) return e > 10 end) +--local usable_skills = imporant_skills({ +-- ["wood cutting"] = 5, +-- ["mining"] = 21, +-- ["fighting"] = 12, +-- ["fishing"] = 10, +--}) +--for k,v in pairs(usable_skills) print(k,":",v) end --prints: +--mining : 21 +--fighting : 12 +function fn.filter(func) + return function(tbl) + local ret = {} + for k,v in pairs(tbl) do + if not func(v) then + ret[k] = v + end + end + return ret + end +end + +--Get the keys of a table in an array +function fn.keys(tbl) + local ret = {} + for k,v in pairs(tbl) do + table.insert(ret,k) + end + return ret +end + +--Get the values of a table in an array +function fn.values(tbl) + local ret = {} + for k,v in pairs(tbl) do + table.insert(ret,v) + end + return ret +end + +--Reverses an array +function fn.reverse(tbl) + local ret = {} + local len = #tbl + for i = 1,len do + ret[len - i + 1] = tbl[i] + end + return ret +end + + +return fn diff --git a/client/data/home.lua b/client/data/home.lua new file mode 100644 index 0000000..bb65aee --- /dev/null +++ b/client/data/home.lua @@ -0,0 +1,34 @@ +--[[ +--Contains the code for a home +--]] +local home = {} + +local home_base = { + add_room = function(self,fromroom,direction) + + end, + rooms = { + + }, + serialize = function(self) + + end, + deserialize = function(self,data) + + end, + add_item_to_room = function(self,room,item,location_desc) + + end +} + +local home_m = {__index=home_base} + +function home.new(player_name,data) + local ret = { + created_by=player_name + } + + return ret +end + +return home diff --git a/client/data/house.lua b/client/data/house.lua new file mode 100644 index 0000000..98d54ac --- /dev/null +++ b/client/data/house.lua @@ -0,0 +1,123 @@ +local room = require("room") +local world = require("world") +local house = {} + +local direction_map = { + north = {0,1,0}, + south = {0,-1,0}, + east = {1,0,0}, + west = {-1,0,0}, + up = {0,0,1}, + down = {0,0,-1}, +} +local opposite = { + north = "south", + south = "north", + east = "west", + west = "east", + up = "down", + down = "up" +} +local house_base = { + create_room = function(self,room_from,direction,roomname) + print("create_room called with roomname",roomname) + local from_loc = room_from.location + local xs,ys,zs = string.match(from_loc,"(%d+)x(%d+)x(%d+)") + local x,y,z = tonumber(xs),tonumber(ys),tonumber(zs) + local vec = {x,y,z} + local sdir = string.lower(direction) + assertf(direction_map[sdir],"Could not find direction %s",sdir) + local to = direction_map[sdir] + for i = 1,3 do + vec[i] = vec[i] + to[i] + end + local newroom_loc = table.concat(vec,"x") + print("Creating a room with name", roomname) + local newroom = room.create_new(roomname,newroom_loc) + print("Settings new room's location to", newroom.location,"newroom is",newroom.name) + room_from.go[sdir] = newroom + newroom.go[opposite[sdir]] = room_from + self.rooms[newroom_loc] = newroom + print("After creating room, house's rooms are ") + for k,v in pairs(self.rooms) do + print(k,v.name) + print("can go") + for i,j in pairs(v.go) do + print("\t",i,j.name) + end + end + end, + destroy_room = function(self,room_from,direction) + local from_loc = room_from.location + local xs,ys,zs = string.match(from_loc,"(%d+)x(%d+)x(%d+)") + local x,y,z = tonumber(xs),tonumber(ys),tonumber(zs) + local vec = {x,y,z} + local sdir = string.lower(direction) + assertf(direction_map[sdir],"Could not find direction %s",sdir) + local to = direction_map[sdir] + for i = 1,3 do + vec[i] = vec[i] + to[i] + end + local roomloc = table.concat(vec,"x") + if roomloc == "1x1x1" then --Don't let them destory the origin room + fail_hint("You cannot destroy the origin room") + return + end + for dirname,dirvec in pairs(direction_map) do + local newvec = {vec[1],vec[2],vec[3]} + for i = 1,3 do + newvec[i] = newvec[i] + dirvec[i] + end + local dc_loc = table.concat(newvec,"x") + if self.rooms[dc_loc] and self.rooms[dc_loc].go[opposite[dirname]] then + self.rooms[dc_loc].go[opposite[dirname]] = nil + end + end + self.rooms[roomloc] = nil + end, + create_doorway = function(self,room_from, direction) + local from_loc = room_from.location + local xs,ys,zs = string.match(from_loc,"(%d+)x(%d+)x(%d+)") + local x,y,z = tonumber(xs),tonumber(ys),tonumber(zs) + local vec = {x,y,z} + local sdir = string.lower(direction) + for i = 1,3 do + vec[i] = vec[i] + direction_map[direction][i] + end + local otherroom = self.rooms[table.concat(vec,"x")] + room_from.go[direction] = otherroom + otherroom.go[opposite[direction]] = room_from + end, + has_room_in_direction = function(self,room_from,direction) + direction = string.lower(direction) + assertf(direction_map[direction],"Did not understand direction: %q",direction) + local from_loc = room_from.location + print("From location is:",from_loc) + local xs,ys,zs = string.match(from_loc,"(%d+)x(%d+)x(%d+)") + local x,y,z = tonumber(xs),tonumber(ys),tonumber(zs) + local vec = {x,y,z} + for i = 1,3 do + vec[i] = vec[i] + direction_map[direction][i] + end + local sdir = string.lower(direction) + return self.rooms[table.concat(vec,"x")] ~= nil + end, +} +local house_m = {__index=house_base} + +function house.create_new(housename,from) + local ret = {name = housename, rooms={}, ownerid = playerid, ["in"]=from} + ret.rooms["1x1x1"] = room.create_new("Front yard","1x1x1") + ret.rooms["1x1x1"].go["south"] = "exit" + setmetatable(house,house_m) + return ret +end +function house.create_from_data(data) + local ret = assert(loadstring(data,"loaded_house")) + setmetatable(ret,house_m) + return ret +end + +house.meta = house_m + +return house diff --git a/client/data/init.lua b/client/data/init.lua new file mode 100644 index 0000000..d6ec4f0 --- /dev/null +++ b/client/data/init.lua @@ -0,0 +1,176 @@ +math.randomseed(os.time()) +function assertf(bool,fmt,...) + assert(bool,string.format(fmt,unpack({...}))) +end +function printf(fmt,...) + print(string.format(fmt,unpack({...}))) +end +-- Override tostring to display more info about the table +--local old_tostring = tostring +--local numtabs = 0 +--function tostring(el) + --if type(el) == "table" then + --numtabs = numtabs + 1 + --local strbuilder = {"{"} + --for k,v in pairs(el) do + --strbuilder[#strbuilder + 1] = string.format("%s%s : %s", string.rep("\t",numtabs), tostring(k), tostring(v)) + --end + --strbuilder[#strbuilder + 1] = "}" + --numtabs = numtabs - 1 + --return table.concat(strbuilder,"\n") + --end + --return old_tostring(el) +--end + + +local w,h = scrw(),scrh() +--gui elements +local textlabel = gui.newlabel({{20,0},{w-20,h - 80}},"") +local hintbox = gui.newlabel({{20,h-80},{w-20,h-40}},"") +local cmdbox = gui.neweditbox({{20,h-40},{w-50,h-20}}) +local cmdbut = gui.newbutton({{w-50,h-40},{w-20,h-20}},"->") +local fail_hint_tex = video.newtexturefromfile("../data/res/fail_hint_box.png") +local fail_hint_guiimg = gui.newiguiimage({w,h-200},true,fail_hint_tex) +local faillabel = gui.newlabel({{w + 30,h-180},{w+220,h-100}},"") +multibox = gui.neweditbox({{20,h/2},{w-20,h-100}},"") +multibox:set_multiline(true) +multibox:setvisible(false) +multibox_donebut = gui.newbutton({{w-100,h-100},{w-20,h-80}},"Done") +multibox_donebut:setvisible(false) +--width=200,height=120 + +function out(text) + local prev = textlabel:gettext() + textlabel:settext(prev .. "\n" .. text) +end +function cls() + textlabel:settext("") +end +function set_hints(...) + local t = table.concat({...},"\t") + hintbox:settext(t) +end +function enable_multibox(bool) + multibox:settext("") + multibox_donebut:setvisible(bool) + multibox:setvisible(bool) +end +function get_multibox() + return multibox +end +function get_multibox_donebut() + return multibox_donebut +end +function clear_cmdbox() + cmdbox:settext("") +end + +local cmd_hooks = {} +function add_cmdbox_hook(func) + table.insert(cmd_hooks,func) +end +local fail_anim = 0 +local fail_queue = {} +function fail_hint(...) + fail_queue[#fail_queue + 1] = table.concat({...}) +end +function fail_hintf(fmt,...) + s = string.format(fmt,unpack({...})) + fail_hint(s) +end + +function GAME.drawPostGui() + if fail_anim > 0 then + if fail_anim < 11 then + fail_hint_guiimg:move({30,0}) + faillabel:move({30,0}) + end + fail_anim = fail_anim - 1 + if fail_anim == 0 then + for i = 1,#fail_queue do + fail_queue[i] = fail_queue[i + 1] + end + end + else + if #fail_queue > 0 then + fail_anim = 100 + fail_hint_guiimg:move({-300,0}) + faillabel:settext(fail_queue[1]) + faillabel:move({-300,0}) + end + end +end + + +local cmds +cmdbox.onChange = function() + for k,v in pairs(cmd_hooks) do + v(cmdbox) + end +end + +--function command_over(text) +--end + +local function run_command() + print("Got command") + local command = cmdbox:gettext() + local parts = {} + for word in string.gmatch(command,"([^%s]+)") do + parts[#parts + 1] = word + end + print("Command parts:") + for k,v in pairs(parts) do + print(k,":",v) + end + local root = parts[1] + for i = 1,#parts do --Remove the first part from the command. + parts[i] = parts[i + 1] + end + if command_over then + command_over(command) + else + if cmds[root] then + print("found command, calling with:") + for k,v in pairs(parts) do + print(k,":",v) + end + cmds[root](unpack(parts)) + cmdbox:settext("") + print("Done calling command") + else + fail_hintf("Unkown command: %s",root) + end + end +end + +--multibox_donebut.onClick = function(self) + --print("Ran multibutton click command") + --print("Over multibut click:", over_multibut_click) + --if over_multibut_click then + --over_multibut_click(self) + --end +--end +cmdbox.onEnter = run_command +cmdbut.onClick = run_command + +GAME.setbackgroundcolor({224,248,208}) +local world = require("world") +local locations = require("locations") +print("about to load localplayer") +print("done loading localplayer") +require("loc_city") +require("loc_beach") +require("loc_forest") +require("loc_mountains") +require("loc_fields") +local player = require("localplayer") +require("interface") +cmds = require("commands") + + +--local house = require("house") +--local save = require("save") +--local nhouse = house.create_new(text) +--local house_data = save.table_to_string(nhouse) +--print("Made house:",house_data) diff --git a/client/data/interface.lua b/client/data/interface.lua new file mode 100644 index 0000000..b8f1222 --- /dev/null +++ b/client/data/interface.lua @@ -0,0 +1,17 @@ +local interface = {} + +local place_types = { + "location", + "house", + "myhouse" +} +local commands = { + location = {"look","goto"}, +} + +add_cmdbox_hook(function(cmdbox) + local newtext = cmdbox:gettext() + print("Got text change:",newtext) +end) + +return interface diff --git a/client/data/item.lua b/client/data/item.lua new file mode 100644 index 0000000..697ed7f --- /dev/null +++ b/client/data/item.lua @@ -0,0 +1,17 @@ +local item = {} + +local item_base = { + get_desc = function(self) + return self.desc + end, +} + +local item_m = {__index = item_base} + +function item.create_new(name,desc,location) + local ret = {name=name,desc=desc,location=location} + setmetatable(ret,item_m) + return ret +end +item.meta = item_m +return item diff --git a/client/data/loc_beach.lua b/client/data/loc_beach.lua new file mode 100644 index 0000000..5471738 --- /dev/null +++ b/client/data/loc_beach.lua @@ -0,0 +1,35 @@ +local locations = require("locations") +local world = require("world") + +local location = { + name = "Beach", + goto_txt = [[ +You take the short path down to the beach. +As you get closer, you can smell the salt from the ocean, and hear the crashing +of the waves against the shoreline. You pass the ruins of several houses that +have sunk into the sand before getting to the shoreline. There are several +players that decided to make use of the beachfront to the left and right of you. +]], + desc = [[ +The beach outside the city seems to attract a certain kind of player to build +their house on the beachfront. Unusually shaped hoses line the beach, one +layer deep the left and right. The occasional flood doesn't seem to bother them. + +The air smells like salt and dead fish, and the ocean's waves crash against the +shoreline in front of you. The sand under your feet is coarse and full of +gravel and dirt. + +There is a path to the City of Beginnings to the north. +]], + settle_txt = [[ +You wander down the beach until you come to the end of the row of houses already +here. You mark out your plot of land with sticks just up from the sand. The house +next to yours seems to be built from intersecting blocks, in unusual colors. +]], + houses = {}, + go = { + {"north", function() return world.locations["City"] end}, + } +} + +locations.add_location(location) diff --git a/client/data/loc_city.lua b/client/data/loc_city.lua new file mode 100644 index 0000000..02fce53 --- /dev/null +++ b/client/data/loc_city.lua @@ -0,0 +1,39 @@ +local locations = require("locations") +local world = require("world") + +local location = { + name = "City", + goto_txt = [[ +You wander through the winding roads that lead up to the great stone walls +around the City of Beginnings. You pass under a portcullis to find yourself +on the main road, the streets lined with novices that decided to settle down +in the first location they found themselves in. +]], + desc = [[The city of Beginnings is a city filled with novice players. +There are stone walls tower around the outside perimeter of the city, protecting +the homes inside from the elements. + +The city only exists thanks to new players waking up and deciding to settle +down immediately. If you choose to settle down here, you will inevitable +be cramped in by other players, lost in the winding roads of the city. + +Mountains loom in the distance to the north +Open fields lie to the east. +There is a beach along the nearby ocean to the south. +There is a dense forest to the West. +]], + settle_txt = [[ +You make your way through the streets until you chance on a narrow plot, squeezed +between two other houses. The road in front of the plot is poorly paved, and the +houses on either side are dilapidated. +]], + houses = {}, + go = { + {"north", function() return world.locations["Mountains"] end}, + {"east", function() return world.locations["Fields"] end}, + {"south", function() return world.locations["Beach"] end}, + {"west", function() return world.locations["Forest"] end} + } +} + +locations.add_location(location) diff --git a/client/data/loc_fields.lua b/client/data/loc_fields.lua new file mode 100644 index 0000000..38ca6bf --- /dev/null +++ b/client/data/loc_fields.lua @@ -0,0 +1,28 @@ +local locations = require("locations") +local world = require("world") + +local location = { + name = "Fields", + goto_txt = [[ +You take the path out of the city towards the open fields to the east. You +pass over rolling hills and sparse farmland. There's nothing around here! + ]], + desc = [[ +The fields are an rural area. Small farmhouses and toolsheds dot the +landscape. The occasional crop plot is planted in neat rows. You see cows +grazing on a nearby hills. There are small saplings growing out of the ground +at random intervals. + +There is a path to the City of Beginnings to the west +]], + settle_txt = [[ +You keep walking through the rolling hills until you can barely see the closest +houses to you, and mark out a plot in the mud with sticks. +]], + houses = {}, + go = { + {"west", function() return world.locations["City"] end}, + } +} + +locations.add_location(location) diff --git a/client/data/loc_forest.lua b/client/data/loc_forest.lua new file mode 100644 index 0000000..43fd8af --- /dev/null +++ b/client/data/loc_forest.lua @@ -0,0 +1,35 @@ +local locations = require("locations") +local world = require("world") + +local location = { + name = "Forest", + goto_txt = [[ +You wander out through the city gates and take the forest path going west. +You approach the only road that cuts through the thick woods, dwarfed by the +trees on either side. +]], + desc = [[ +The forest is vast, and it's easy to get lost if you don't stick to the path. +Occasionally a trail leads off the path, sometimes it will circle around a +rock or tree. Other times trails seemingly disappears into the underbrush. A stream +comes down from the mountains to the north-east, running along your trail +for a while before turning back into the deep underbrush. + +Soon your come to a place where the well-worn trail stops, and there are only +faint paths leading deeper into the foliage in every direction. + +There is a path leading to the City of Beginnings to the east. +]], + settle_txt = [[ +You pick a direction from the end of the path, one that looks like no one has +gone down before, and start walking. After a while you decide you've walked +far enough, you commit the path you took here to memory, and start marking the +area you plan to build in with sticks and twigs. +]], + houses = {}, + go = { + {"east", function() return world.locations["City"] end}, + } +} + +locations.add_location(location) diff --git a/client/data/loc_mountains.lua b/client/data/loc_mountains.lua new file mode 100644 index 0000000..e8450ee --- /dev/null +++ b/client/data/loc_mountains.lua @@ -0,0 +1,32 @@ +local locations = require("locations") +local world = require("world") + +local location = { + name = "Mountains", + goto_txt = [[ +You take the path up the mountains. Where the pine trees end, your real trek +begins. The ice, uninhibited by the trees makes the path up the mountain +treacherous to hike. You persist forward, and eventually reach a landing a +little below the summit, where you see a few stone home built into the +mountainside. +]], + desc = [[ +The mountainside is a distant but secure place to build a home. The homes +here are built partly into the mountain, with the occasional wooden frame +sticking out. The avalanches make the area treacherous, and the inhabitants +stock up on food and other necessities in case they are snowed in. + +There is a path to the City of Beginnings to the south +]], + settle_txt = [[ +You brave the icy paths to find a small flat area to start building. You mark +out the plot with large stones. The road in front of your plot is covered in +snow. You cannot see any other homes around you. +]], + houses = {}, + go = { + {"south", function() return world.locations["City"] end}, + } +} + +locations.add_location(location) diff --git a/client/data/localplayer.lua b/client/data/localplayer.lua new file mode 100644 index 0000000..74fbf0a --- /dev/null +++ b/client/data/localplayer.lua @@ -0,0 +1,147 @@ +local localplayer = {} +local world = require("world") +local net = require("net") +local save = require("save") +print("Doing local player") + +local directions = { + "north","south","east","west","up","down" +} +local directions_index = {} +for k,v in pairs(directions) do + directions_index[v] = k +end +--print("In localplayer, world.locations are:",world.locations) +--for k,v in pairs(world.locations) do + --print(k,":",v) +--end +local lp_base = { + location = world.locations["City"], + has_settled = false, + go = function(self,dir) + dir = string.lower(dir) + if self.location.is_location then + local to + for k,v in pairs(self.location.go) do + if v[1] == dir then + to = v[2]() + break + end + end + self.location = to + cls() + out(self.location.goto_txt) + else --We're in a house/room + local toroom = self.location.go[dir] + --print("got to room:",toroom) + if toroom == "exit" then + print("special exit room") + self.location = self.in_house["in"] + self.in_house = nil + self.owns = false + cls() + out(self.location.goto_txt) + return + end + self.location = toroom + cls() + out(toroom:get_room_desc()) + end + end, + goto_house = function(self,location,house) + print("going to ",name) + print("Got location:",location,"Got name:",house) + local house = net.get_house(location,house) + self.in_house = house + local init_room_name = "1x1x1" + local init_room = house.rooms[init_room_name] + local init_room_meta = getmetatable(init_room).__index + print("init_room_meta",init_room_meta) + local owner = net.do_i_own(location,house.name,self.id) + print("Looked at do_i_own:",owner) + if owner then + self.owns = true + else + self.owns = false + end + self.location = init_room + cls() + out(init_room:get_room_desc()) + print("I'm in the inital room!",init_room) + end, + goto_location = function(self,loc) + self.in_house = nil + print("Setting location to",loc) + self.location = loc + cls() + out(self.location.goto_txt) + end, + --goto_location = function(self,name) + --assert(name ~= nil,"tried to go to a nil location") + --print("Self is",self,"name is",name) + --print("valid locations are:") + --for k,v in pairs(world.locations) do + --print(k,":",v) + --end + --assertf(world.locations[name],"The location %q does not exist.",name) + --cls() + --out(world.locations[name].goto_txt) + --localplayer.location = name + ----out(world.locations[name].desc) + --end, + get_loc = function(self) + --Check if the player is in one of the locations + print("Trying to get location:",self.location) + print("World locations:",#world.locations) + for k,v in pairs(world.locations) do + print(k,":",v) + end + local loc + if world.locations[self.location] then + loc = world.locations[self.location] + end + print("Got location:",loc) + return loc + end, +} +local lp_m = {__index = lp_base} + +local function load_save() + return require("savedata") +end +local success , data = pcall(load_save) +if success then + print("setting local player to saved data") + localplayer = data + setmetatable(localplayer,lp_m) + out(localplayer.location.desc) + if not localplayer.has_settled then + world.basic_commands[#world.basic_commands + 1] = "settle" + end +else + print("Creating new player") + out([[ +Welcome to HTA, the Home Text Adventure. The text here describes where you +are or what your are doing. Use the text box at the bottom to enter commands. +You can submit commands by pressing the button to the right of the textbox, +or by pressing the Enter key. + +Hints for what kinds of things you can type in are displayed right above the +text box. Try typing "look" in the command box. + +You wake up in the City of Beginnings +]]) + setmetatable(localplayer,lp_m) + localplayer.id = math.random() + localplayer.owns = false + localplayer.in_house = nil + world.basic_commands[#world.basic_commands + 1] = "settle" + set_hints(unpack(world.basic_commands)) + local f = io.open("../data/savedata.lua","w") + f:write(save.table_to_string(localplayer)) + f:close() +end + + + +return localplayer diff --git a/client/data/locations.lua b/client/data/locations.lua new file mode 100644 index 0000000..183425e --- /dev/null +++ b/client/data/locations.lua @@ -0,0 +1,44 @@ +local world = require("world") +local net = require("net") +world.locations = world.locations or {} +local loc = {} + +local required_fields = { + name = "string", + desc = "string", + goto_txt = "string", + go = "table", + settle_txt = "string" +} + +local location_base = { + get_desc = function(self) + local houses = net.ask_for_homes(self.name,1) + self.last_houses = houses + local sb = {self.desc} + for k,v in pairs(houses) do + print("Adding ", v) + sb[#sb + 1] = string.format("%s is here",v) + end + return table.concat(sb,"\n") + end, + houses = {}, + is_location = true +} + +local location_m = {__index = location_base} + +function loc.add_location(tbl) + print("Added location:",tbl.name) + assert(type(tbl) == "table","Tried to register a location that was not a table") + for k,v in pairs(required_fields) do + assertf(tbl[k],"Tried to register a location without a %s field",k) + assertf(type(tbl[k]) == v,"Tried to register a location with a %s field that should have been a %s, but was a %s",k,v,type(tbl[k])) + end + assert(world.locations[tbl.name] == nil) + setmetatable(tbl,location_m) + world.locations[tbl.name] = tbl +end + + +return loc diff --git a/client/data/net.lua b/client/data/net.lua new file mode 100644 index 0000000..c3eec15 --- /dev/null +++ b/client/data/net.lua @@ -0,0 +1,146 @@ + +local snet = {} +local room = require("room") +local item = require("item") +local house = require("house") +local socket = net.newsocket(net.REQ) + +--Some server in the cloud, running the same stuff in server/* +socket:connect("tcp://34.73.161.231:5555") + +function snet.ask_for_homes(location,index) + socket:send(function(stream) + stream:writestring("get_houses") + stream:writestring(location) + stream:writeint(index) + end) + local stream = socket:block_recv() + local num_homes = stream:readint() + local ret = {} + printf("Found %d homes",num_homes) + for i = 1,num_homes do + local home_name = stream:readstring() + local nice_name = string.match(home_name,"(.*).lua") + print(nice_name) + ret[#ret + 1] = nice_name + end + return ret + --print("got homes:",stream:readstring()) +end + +function snet.ask_for_all_homes(location) + socket:send(function(stream) + stream:writestring("get_all_houses") + stream:writestring(location) + end) + local stream = socket:block_recv() + local ret = {} + for i = 1,stream:readint() do + local home_name = stream:readstring() + local nice_name = string.match(home_name,"(.*).lua") + ret[#ret + 1] = nice_name + end + return ret +end + +function snet.house_exists(location,housename) + socket:send(function(stream) + stream:writestring("house_exists") + stream:writestring(location) + stream:writestring(housename) + end) + local stream = socket:block_recv() + return stream:readint() == 1 +end + +function snet.settle_at(myid,location,name) + socket:send(function(stream) + stream:writestring("settle") + stream:writestring(location) + stream:writestring(name) + stream:writedouble(myid) + end) + local stream = socket:block_recv() + +end + +function snet.is_name_available(name,loc_name) + socket:send(function(stream) + stream:writestring("is_name_avaliable") + stream:writestring(name) + stream:writestring(loc_name) + end) + local stream = socket:block_recv() + return stream:readint() == 1 +end + +function snet.claim_house(name,loc_name,playerid) + socket:send(function(stream) + stream:writestring("claim_house") + stream:writestring(name) + stream:writestring(loc_name) + stream:writestring(tostring(playerid)) + end) + local stream = socket:block_recv() +end + +function snet.write_house(player_id,housedata) + socket:send(function(stream) + stream:writestring("write_house") + stream:writestring(tostring(player_id)) + stream:writestring(housedata) + end) + local stream = socket:block_recv() + print("Done getting stream back") +end + +function snet.get_house(loc_name,housename) + socket:send(function(stream) + stream:writestring("get_house") + stream:writestring(loc_name) + stream:writestring(housename) + end) + local stream = socket:block_recv() + print("Got house back") + local housedata = stream:readstring() + local this_house = assert(loadstring(housedata,housename))() + setmetatable(this_house,house.meta) + print("house loaded correctly",house) + for room_name,this_room in pairs(this_house.rooms) do + print("setting item metas for ",this_room,":",type(this_room),"---",this_room.items) + for i,this_item in pairs(this_room.items) do + print(string.format("Setting item metas for %q %q",tostring(i),tostring(this_item))) + --print("setting item metas for",i,":",this_item) + setmetatable(this_item,item.meta) + end + print("Setting meta table for this room") + setmetatable(this_room,room.meta) + print("done setting meta table") + end + print("returning house") + return this_house +end + +function snet.do_i_own(loc_name,housename,playerid) + print("doing do_i_own") + socket:send(function(stream) + print("Starting to write to stream") + stream:writestring("do_i_own") + print("one") + stream:writestring(loc_name) + print("two",housename) + stream:writestring(housename) + print("three",playerid) + --print("three",tostring(playerid)) + stream:writestring(tostring(playerid)) + print("Wrote everything to send") + end) + print("Done with sending") + local stream = socket:block_recv() + local ret = stream:readint() + print("got back:",ret) + print("Done with do_i_own") + return ret == 1 +end + +return snet diff --git a/client/data/res/fail_hint_box.png b/client/data/res/fail_hint_box.png Binary files differnew file mode 100644 index 0000000..4f3d079 --- /dev/null +++ b/client/data/res/fail_hint_box.png diff --git a/client/data/res/fail_hint_box_raw.png b/client/data/res/fail_hint_box_raw.png Binary files differnew file mode 100644 index 0000000..4ea1280 --- /dev/null +++ b/client/data/res/fail_hint_box_raw.png diff --git a/client/data/res/fail_hint_box_raw.xcf b/client/data/res/fail_hint_box_raw.xcf Binary files differnew file mode 100644 index 0000000..dc8b7a1 --- /dev/null +++ b/client/data/res/fail_hint_box_raw.xcf diff --git a/client/data/res/font.xml b/client/data/res/font.xml Binary files differnew file mode 100644 index 0000000..3665304 --- /dev/null +++ b/client/data/res/font.xml diff --git a/client/data/res/font0.png b/client/data/res/font0.png Binary files differnew file mode 100644 index 0000000..d14887b --- /dev/null +++ b/client/data/res/font0.png diff --git a/client/data/res/font1.png b/client/data/res/font1.png Binary files differnew file mode 100644 index 0000000..ebdaa21 --- /dev/null +++ b/client/data/res/font1.png diff --git a/client/data/res/font2.png b/client/data/res/font2.png Binary files differnew file mode 100644 index 0000000..aec13da --- /dev/null +++ b/client/data/res/font2.png diff --git a/client/data/room.lua b/client/data/room.lua new file mode 100644 index 0000000..410b08e --- /dev/null +++ b/client/data/room.lua @@ -0,0 +1,68 @@ +local room = {} +local item = require("item") + +local room_base = { + add_item = function(self,itemname,itemdesc,itemlocation) + local newitem = item.create_new(itemname,itemdesc,itemlocation) + self.items[#self.items + 1] = newitem + end, + remove_item = function(self,itemname,itemdesc,itemlocation) + local to_remove = {} + for k,v in pairs(self.items) do + if v.name == itemname and v.desc == itemdesc and v.itemlocation == itemlocation then + to_remove[#to_remove + 1] = k + end + end + for k,v in pairs(to_remove) do + table.remove(self.items,v) + end + end, + get_items_names = function(self) + local ret = {} + for k,v in pairs(self.items) do + ret[#ret + 1] = v.name + end + return ret + end, + get_room_desc = function(self) + local sb = {} + sb[#sb + 1] = string.format("You are in a %s",self.name) + sb[#sb + 1] = string.format(self.desc) + for itemnum,item in pairs(self.items) do + sb[#sb + 1] = string.format("There is a %s %s",item.name,item.location) + end + for direction,room in pairs(self.go) do + if room == "exit" then + sb[#sb + 1] = string.format("There is an exit to the %s",direction) + else + local name = room.name + local sdir = string.lower(direction) + if sdir == "up" then + sb[#sb + 1] = string.format("There is a %s above you",name) + elseif sdir == "down" then + sb[#sb + 1] = string.format("There is a %s below you",name) + else + sb[#sb + 1] = string.format("There is a %s to the %s",name,direction) + end + end + end + return table.concat(sb,"\n") + end +} + +local room_m = {__index = room_base} + +function room.create_new(n,loc) + local ret = { + name=n, + items={}, + desc="", + go={}, + location=loc + } + print("Created room:",ret) + setmetatable(ret,room_m) + return ret +end +room.meta = room_m +return room diff --git a/client/data/save.lua b/client/data/save.lua new file mode 100644 index 0000000..137a32f --- /dev/null +++ b/client/data/save.lua @@ -0,0 +1,64 @@ +--[[ +Functions for turning a table into lua code that will re-create the table. +]] + +local fn = require("fn") +local tts = {} + +function tts.table_to_string(tbl) + --Collect all of our tables first, + --so that we don't break when we have recursive tables. + local tables = {} + local table_order = {} + local function tables_helper(t) + tables[t] = #table_order + 1 + table_order[#table_order + 1] = t + for k,v in pairs(t) do + if type(k) == "table" and not tables[k] then + tables_helper(k) + end + if type(v) == "table" and not tables[v] then + tables_helper(v) + end + end + end + tables_helper(tbl) + + --Get the string representation of an element + local errfun = function(e) error("Cannot format a " .. type(e)) end + local rep_map = { + --things we can format + number = function(e) return string.format("%f",e) end, + string = function(e) return string.format("%q",e) end, + boolean = function(e) return e and "true" or "false" end, + table = function(e) + assertf(tables[e] ~= nil,"Could not find dependency table %s",tostring(e)) + return string.format("table_%d",tables[e]) + end, + --things we can't format + ["function"] = errfun, + coroutine = errfun, + file = errfun, + userdata = errfun, + --nil can never happen + } + local sb = {} + --Create all the variables first, so that recursive tables will work + for n,_ in pairs(table_order) do + sb[#sb + 1] = string.format("local table_%d = {}",n) + end + --Go backwards through tables, since that should be the + --"dependency" order + for i = #table_order, 1, -1 do -- -1 is needed in case #table_order == 0 + local tstr = {} + local this_table = table_order[i] + for k,v in pairs(this_table) do + tstr[#tstr + 1] = string.format("table_%d[%s] = %s",i,rep_map[type(k)](k), rep_map[type(v)](v)) + end + sb[#sb + 1] = table.concat(tstr,"\n") + end + sb[#sb + 1] = "return table_1" + return table.concat(sb,"\n\n"); +end + +return tts diff --git a/client/data/savedata.lua b/client/data/savedata.lua new file mode 100644 index 0000000..68b468b --- /dev/null +++ b/client/data/savedata.lua @@ -0,0 +1,6 @@ +local table_1 = {} + +table_1["id"] = 0.876600 +table_1["owns"] = false + +return table_1
\ No newline at end of file diff --git a/client/data/world.lua b/client/data/world.lua new file mode 100644 index 0000000..033e026 --- /dev/null +++ b/client/data/world.lua @@ -0,0 +1,5 @@ +local world = {} + +world.basic_commands = {"look","go"} + +return world |
