1local function onevent(ev, ...) 2 local vv, r 3 if stead.api_atleast(1, 6, 3) then 4 vv, r = stead.call(game, ev, ...); 5 if r == false then 6 return vv, false 7 end 8 if vv == false then 9 return nil, false 10 end 11 return vv 12 end 13end 14 15local go = function (self, where, back, noenter, noexit, nodsc) 16 local was = self.where; 17 local need_scene = false; 18 local ret 19 20 if not stead.in_walk_call then 21 ret = function(rc) stead.in_walk_call = false return nil end 22 else 23 ret = function(rc) return rc end 24 end 25 26 stead.in_walk_call = true 27 28 if where == nil then 29 return nil, ret(false) 30 end 31 32 if not isRoom(stead.ref(where)) then 33 error ("Trying to go nowhere: "..where); 34 end 35 36 if not isRoom(stead.ref(self.where)) then 37 error ("Trying to go from nowhere: "..self.where); 38 end 39 40 if stead.in_entered_call or stead.in_onexit_call then 41 error ("Do not use walk from left/entered action! Use exit/enter action instead:" .. self.where); 42 end 43 44 local v, r, jump; 45 46 if not isVroom(stead.ref(where)) and not stead.in_exit_call and not noexit then 47 stead.in_exit_call = true -- to break recurse 48 v,r = stead.call(stead.ref(self.where), 'exit', stead.ref(where)); 49 stead.in_exit_call = nil 50 if r == false or (stead.api_atleast(1, 3, 0) and v == false and r == nil) then 51 return v, ret(r) 52 end 53 if stead.api_atleast(2, 4, 0) then 54 jump = stead.rawget(_G, 'PLAYER_MOVED') 55 else 56 jump = (self.where ~= was) 57 end 58 if jump then 59 where = stead.deref(self.where) -- jump 60 end 61 end 62 63 local res = v; 64 v = nil; 65 66 if not isVroom(stead.ref(where)) then 67 self.where = stead.deref(where); 68 end 69 70 if not jump and not noenter then 71 v, r = stead.call(stead.ref(where), 'enter', stead.ref(was)); 72 if r == false or (stead.api_atleast(1, 3, 0) and v == false and r == nil) then 73 self.where = was; 74 return stead.par(stead.scene_delim, res, v), ret(r) 75 end 76 end 77 78 if stead.api_atleast(2, 4, 0) then 79 need_scene = not stead.rawget(_G, 'PLAYER_MOVED'); 80 else 81 need_scene = not (stead.ref(where) ~= stead.ref(self.where)) 82 end 83 84 res = stead.par(stead.scene_delim, res, v); 85 86 if not back then 87 stead.ref(where).__from__ = stead.deref(was); 88 end 89 90 ret() 91 92 stead.rawset(_G, 'PLAYER_MOVED', true) 93 if need_scene and not nodsc then 94 stead.need_scene() 95 end 96 97 if not stead.in_walk_call then 98 local to = self.where 99 if not noexit then 100 self.where = was 101 stead.in_onexit_call = true 102 v = stead.call(stead.ref(was), 'left', stead.ref(to)); 103 stead.in_onexit_call = false 104 res = stead.par(stead.scene_delim, res, v); 105 end 106 107 self.where = stead.deref(to) 108 109 if not noenter then 110 stead.in_entered_call = true 111 v = stead.call(stead.ref(to), 'entered', stead.ref(was)); 112 stead.in_entered_call = false 113 res = stead.par(stead.scene_delim, res, v); 114 end 115 116 if stead.tonum(stead.ref(to).__visited) then 117 stead.ref(to).__visited = stead.ref(to).__visited + 1; 118 elseif stead.here().__visited == nil then 119 stead.ref(to).__visited = 1 120 end 121 if not stead.api_atleast(1, 6, 3) and isDialog(stead.ref(to)) then 122 stead.dialog_rescan(stead.ref(to)) 123 end 124 end 125 return res; 126end 127 128stead.player_go = function(self, where) -- cmd iface 129 local w = stead.ref(self.where).way:srch(where); 130 if not w then 131 return nil,false 132 end 133 return self:walk(w); 134end 135 136stead.player_walk = function(self, where, ...) -- real work 137 local v, r, vv; 138 vv, r = onevent('onwalk', stead.ref(where), ...); 139 if vv == false then 140 return 141 end 142 if r == false then 143 return vv 144 end 145 v, r = stead.go(self, where, ...); 146 if stead.type(vv) == 'string' then 147 v = stead.par(stead.space_delim, vv, v); 148 end 149 return v, r; 150end 151 152stead.player_back = function(self) -- deprecated 153 error ("Do not use stead.me():back(). It's deprecated.", 2) 154end 155 156stead.back = function(w) 157 if isDialog(stead.here()) and not isDialog(stead.from()) then 158 return stead.walkout(w); 159 end 160 return stead.walkback(w); 161end 162back = stead.back 163 164stead.walkback = function(w) 165 if isRoom(stead.ref(w)) then 166 return stead.me():walk(w, true); 167 end 168 return stead.me():walk(stead.from(), true); 169end 170walkback = stead.walkback 171 172stead.walk = function(what, back, noenter, noexit, nodsc, ...) 173 return stead.me():walk(what, back, noenter, noexit, nodsc, ...); 174end 175walk = stead.walk 176 177stead.walkin = function(what) 178 return stead.me():walk(what, false, false, true); 179end 180walkin = stead.walkin 181 182stead.walkout = function(what) 183 if isRoom(stead.ref(what)) then 184 return stead.me():walk(what, true, true, false, true); 185 end 186 return stead.me():walk(stead.from(), true, true, false, true); 187end 188walkout = stead.walkout 189 190function visited(w) 191 if not w then w = stead.here() end 192 w = stead.ref(w) 193 if w == nil then 194 return nil; 195 end 196 if not isRoom(w) then 197 error ("Wrong parameter to visited.", 2); 198 end 199 return w.__visited 200end 201stead.visited = visited 202 203function visits(w) 204 local n = stead.visited(w) 205 if not n then n = 0 end 206 return n 207end 208stead.visits = visits 209 210iface.fmt = function(self, cmd, st, moved, r, av, objs, pv) -- st -- changed state (main win), move -- loc changed 211 local l, vv 212 if st then 213 av = txtem(av); 214 pv = txtem(pv); 215-- if not PLAYER_MOVED then 216 r = txtem(r) 217-- end 218 if isForcedsc(stead.here()) or stead.rawget(_G, 'NEED_SCENE') then 219 l = stead.here():scene(); 220 end 221 end 222 if moved then 223 vv = stead.fmt(stead.cat(stead.par(stead.scene_delim, r, l, av, objs, pv), '^')); 224 else 225 vv = stead.fmt(stead.cat(stead.par(stead.scene_delim, l, r, av, objs, pv), '^')); 226 end 227 return vv 228end 229 230stead.go = function(...) 231 local r,v = go(...) 232 if stead.type(r) == 'string' and stead.cctx() then 233 stead.pr (r) 234 end 235-- if stead.in_life_call then 236-- ACTION_TEXT = nil 237-- end 238 if r == nil and v == nil then 239 if stead.cctx() then 240 stead.cctx().action = true 241 else 242 r = true 243 end 244 end 245 return r,v 246end 247 248iface.cmd = stead.hook(iface.cmd, function(f, ...) 249 stead.rawset(_G, 'NEED_SCENE', nil) 250 return f(...) 251end) 252 253player = stead.inherit(player, function(v) 254 v.look = function(s) 255 if not stead.started then 256 game:start() 257 end 258 if game._time == 0 then 259 return stead.walk(stead.here(), false, false, true); 260 end 261 stead.need_scene() 262 if stead.api_atleast(1, 3, 5) then 263 return true -- force action 264 end 265 end 266 return v 267end) 268 269pl = player(pl) -- reinit 270-- vim:ts=4 271