File: libtrain_1.xml

package info (click to toggle)
enigma 1.30%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 76,132 kB
  • sloc: xml: 162,251; cpp: 67,393; ansic: 28,606; makefile: 1,986; sh: 1,298; yacc: 288; perl: 84; sed: 16
file content (206 lines) | stat: -rw-r--r-- 7,905 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<el:level xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://enigma-game.org/schema/level/1 level.xsd" xmlns:el="http://enigma-game.org/schema/level/1">
  <el:protected>
    <el:info el:type="library">
      <el:identity el:title="" el:id="lib/libtrain"/>
      <el:version el:score="1" el:release="1" el:revision="1" el:status="released"/>
      <el:author  el:name="Ronald Lamprecht" el:email="" el:homepage=""/>
      <el:copyright>Copyright © 2009 Ronald Lamprecht</el:copyright>
      <el:license el:type="GPL v2.0 or above" el:open="true"/>
      <el:compatibility el:enigma="1.10">
        <el:dependency el:path="lib/liblua" el:id="lib/liblua" el:release="1" el:preload="true"/>
      </el:compatibility>
      <el:modes el:easy="false" el:single="false" el:network="false"/>
      <el:comments/>
      <el:score el:easy="-" el:difficult="-"/>
    </el:info>
    <el:luamain><![CDATA[
res.train_railways = {}

function res.train(subresolver, ...)
    -- syntax: ... = <prefixkey>
    assert_bool(is_resolver(subresolver), "res.train first argument (subresolver)", 2)
    local args = {...}
    local context = {res.train_implementation, res.train_finalization, subresolver}
    
    context.newori = {[WEST]={WEST, NORTH, SOUTH}, [SOUTH]={SOUTH, WEST, EAST},
                      [EAST]={EAST, SOUTH, NORTH}, [NORTH]={NORTH, EAST, WEST}}
    context.suffix = nil
    context.suffix_init = false
    context.hits = args
    context.edges = {}
    context.track = {}
    context.trains = {}
    context.railway = 0
    context.subresolver = subresolver
    
    for i, v in ipairs(args) do
        assert_type(v, "res.train argument "..i+1, 2, "string", "table")
        if i > 1 and type(args[i]) == "string" then
            context.hits[i] = {args[i]}
        end
    end
    
    if type(args[1]) == "table" then
        context.suffix_init = true
    else
        context.suffix = args[1]
    end
    setmetatable(context, res.metatable)
    table.insert(res.train_railways, context)
    context.railway = #res.train_railways
    return context
end

function res.train_implementation(context, evaluator, key, x, y)
    if not context.suffix_init then
        if #(context.suffix) >= #key then
            context.suffix = nil
            context.hits[1] = {context.hits[1]}
        else  -- now we are sure we have a suffix as argument 2
            table.remove(context.hits, 1)
        end
        context.suffix_init = true
    end
    
    local replacement = nil
    for i, hit in ipairs(context.hits) do
        if hit[1] == key then
--            print("train: direct hit '"..key.."'")
            replacement = hit[2] or ""
            if hit["edge"] == true then
                table.insert(context.edges, po(x,y))
            else
                table.insert(context.track, po(x,y))
            end
            if hit["train"] ~= nil then
                local newtrain = lib.lua.deep_copy(hit["train"])
                newtrain["pos"] = po(x, y)
                if newtrain["interval"] == nil then
                    newtrain.interval=0.25
                end
                table.insert(context.trains, newtrain)
                newtrain.index = #context.trains
                newtrain.railway = context.railway
                newtrain.tick = res.train_usertick
            end
            break
        end
    end
    
    if replacement == nil and context.suffix ~= nil and 
            key:find(context.suffix, -#context.suffix, true) ~= nil then
--        print("train: suffix found")
        replacement = key:sub(1, -1 - #context.suffix) .. string.rep(" ", #context.suffix)
--        print("train: suffix replacement '"..replacement.."'")
        table.insert(context.track, po(x,y))
    end
    
    if replacement == nil then
        return evaluator(context[3], key, x, y)
    else
        return cond(replacement ~=  "", evaluator(context[3], replacement, x, y), {"nil"})
    end
end

function res.train_finalization(context)
    assert_bool(#context.edges == 0 or #context.edges == 2, "libtrain: illegal number of track edges:" .. #context.edges)
    if #context.edges == 2 then
        local minx = math.min(context.edges[1].x, context.edges[2].x)
        local maxx = math.max(context.edges[1].x, context.edges[2].x)
        local miny = math.min(context.edges[1].y, context.edges[2].y)
        local maxy = math.max(context.edges[1].y, context.edges[2].y)
        assert_bool(minx ~= maxx, "libtrain error: both edges in same column") 
        assert_bool(miny ~= maxy, "libtrain error: both edges in same row")
        table.insert(context.track, po(minx+1, miny))
        table.insert(context.track, po(maxx-1, miny))
        table.insert(context.track, po(maxx, miny+1))
        table.insert(context.track, po(maxx, maxy-1))
        table.insert(context.track, po(maxx-1, maxy))
        table.insert(context.track, po(minx+1, maxy))
        table.insert(context.track, po(minx, maxy-1))
        table.insert(context.track, po(minx, miny+1))
    end
    local tracklength = 0
    local train = lib.lua.deep_copy(context.trains[1])
    local trainlength = 0
    local startpos = train.pos
    local positions = nil
    repeat
         res.train_move(context, train)
         if positions == nil then
             positions = train["pos"]
         else
             positions = positions .. train["pos"]
         end
         tracklength = tracklength + 1
         trainlength = trainlength + 1
         if train.length == trainlength then
             local loco = lib.lua.deep_copy(train)
             loco[1], loco[2] = loco[2], loco[1]
             loco.length = nil
             table.insert(context.trains, loco)
             loco.index = #context.trains
             loco.railway = context.railway
             loco.tick = res.train_usertick
             if type(loco.name) == "string" then
                 loco.name = loco.name .. "_front"
             end
         end
         for i, tr in ipairs(context.trains) do
             if tr.pos == train.pos then
                 for i = 1, #positions do
                     local pos = positions[i]
                     wo[pos] = wo:_evaluate(context.subresolver, tr[1], pos.x, pos.y)
                 end
                 train = lib.lua.deep_copy(tr)
                 trainlength = 0
                 positions = nil
                 break
             end
         end
    until train.pos == startpos or tracklength > 2000
    
    for i, tr in ipairs(context.trains) do
        wo:add({"ot_timer", "res.train.timer", target="res.train_tick", interval=tr.interval, _railway=context.railway, _train=tr.index})
        tr.timer = no["res.train.timer"]
    end

    return
end


function res.train_move(context, train)
    for i=1,3 do
        local neworientation = (context.newori[train.orientation])[i]
        local newpos = train["pos"] + ORI2DIR[neworientation]
        if newpos:exists() then
            for j, trackpos in ipairs(context.track) do
                if trackpos == newpos then
                    train["pos"] = newpos
                    train.orientation = neworientation
                    return
                end
            end
        end
    end
    train["pos"] = train["pos"] + ORI2DIR[train.orientation]
end

function res.train_tick(value, sender)
    local context = res.train_railways[sender._railway]
    local train = context.trains[sender._train]
    res.train_move(context, train)
    wo[train.pos] = wo:_evaluate(context.subresolver, train[1], train.pos.x, train.pos.y)
end

function res.train_usertick(train)
    local context = res.train_railways[train.railway]
    res.train_move(context, train)
    wo[train.pos] = wo:_evaluate(context.subresolver, train[1], train.pos.x, train.pos.y)
end
    ]]></el:luamain>
    <el:i18n>
    </el:i18n>
  </el:protected>
</el:level>