diff --git a/battlefield.lua b/battlefield.lua --- a/battlefield.lua +++ b/battlefield.lua @@ -1,2 +1,294 @@ -battlefield = function(tab) { -} \ No newline at end of file +_kh.bf_calcDistance = function(x1, y1, x2, y2) + return math.max(math.abs(x2 - x1), math.abs(y2 - y1)); +end; + +_kh.bf_calcDirection = function(x1, y1, x2, y2) + -- 0 - close by, 1-8 - north to north-west clockwise, 9 - too far + local dist = _kh.bf_calcDistance(x1,y1,x2,y2); + if (dist == 0) then + return 0; + elseif (dist == 1) then + if (x1 == x2 and y1 > y2) then + return 1; + elseif (x1 < x2 and y1 > y2) then + return 2; + elseif (x1 < x2 and y1 == y2) then + return 3; + elseif (x1 < x2 and y1 < y2) then + return 4; + elseif (x1 == x2 and y1 < y2) then + return 5; + elseif (x1 > x2 and y1 < y2) then + return 6; + elseif (x1 > x2 and y1 == y2) then + return 7; + elseif (x1 > x2 and y1 > y2) then + return 8; + end; + else + return 9; + end; +end; + +battlefield = function(tab) + local make_turn = tab.make_turn; + tab.check_walk = function(s) + bf_north:enable(); + bf_northeast:enable(); + bf_east:enable(); + bf_southeast:enable(); + bf_south:enable(); + bf_southwest:enable(); + bf_west:enable(); + bf_northwest:enable(); + + if (s.plY == 1) then + bf_north:disable(); + bf_northeast:disable(); + bf_northwest:disable(); + elseif (s.plY == 5) then + bf_south:disable(); + bf_southeast:disable(); + bf_southwest:disable(); + end; + + if (s.plX == 1) then + bf_west:disable(); + bf_southwest:disable(); + bf_northwest:disable(); + elseif (s.plX == 5) then + bf_east:disable(); + bf_southeast:disable(); + bf_northeast:disable(); + end; + end; + + local entered = tab.entered; + + tab.entered = function(s) + s:check_walk(); + if (type(entered) == 'function') then + entered(s); + else + return entered; + end; + end; + + tab.make_turn = function(s) + for i = 1, #s.obj do + if (type(s.obj[i].make_turn) == 'function') then + s.obj[i]:make_turn(); + end; + end; + + if (make_turn) then + make_turn(s); + end; + + s:check_walk(); + end; + + tab.getDistance = _kh.bf_calcDistance; + tab.getDirection = _kh.bf_calcDirection; + + if (not tab.obj) then + tab.obj = {}; + end; + + if (not tab.pic) then + tab.pic = function(s) + local v = "images/battle_bcg.png;images/player.png@" .. tostring(s.plX * 32 - 32) .. "," .. tostring(s.plY * 32 - 32); + for i = 1, #s.obj do + if (not(s.obj[i]:disabled()) and s.obj[i].pic and s.obj[i].x and s.obj[i].y) then + v = v .. ";" .. s.obj[i].pic .. "@" .. tostring(s.obj[i].x * 32 - 32) .. "," .. tostring(s.obj[i].y * 32 - 32); + end; + end; + print(v); + return v; + end; + end; + + table.insert(tab.obj, 'bf_north'); + table.insert(tab.obj, 'bf_northeast'); + table.insert(tab.obj, 'bf_east'); + table.insert(tab.obj, 'bf_southeast'); + table.insert(tab.obj, 'bf_south'); + table.insert(tab.obj, 'bf_southwest'); + table.insert(tab.obj, 'bf_west'); + table.insert(tab.obj, 'bf_northwest'); + table.insert(tab.obj, 'bf_wait'); + + return room(tab); +end; + +bf_north = obj { + nam = "north", + dsc = "{На север}", + act = function(s) + here().plY = here().plY - 1; + p("Вы идете на север"); + here():make_turn(); + end; +}; + +bf_northeast = obj { + nam = "northeast", + dsc = "{На северо-восток}", + act = function(s) + here().plX = here().plX + 1; + here().plY = here().plY - 1; + p("Вы идете на северо-восток."); + here():make_turn(); + end; +}; + +bf_east = obj { + nam = "east", + dsc = "{На восток}", + act = function(s) + here().plX = here().plX + 1; + p("Вы идете на восток."); + here():make_turn(); + end; +}; + +bf_southeast = obj { + nam = "southeast", + dsc = "{На юго-восток}", + act = function(s) + here().plX = here().plX + 1; + here().plY = here().plY + 1; + p("Вы идете на юго-восток."); + here():make_turn(); + end; +}; + +bf_south = obj { + nam = "south", + dsc = "{На юг}", + act = function(s) + here().plY = here().plY + 1; + p("Вы идете на юг."); + here():make_turn(); + end; +}; + +bf_southwest = obj { + nam = "southwest", + dsc = "{На юго-запад}", + act = function(s) + here().plX = here().plX - 1; + here().plY = here().plY + 1; + p("Вы идете на юго-запад."); + here():make_turn(); + end; +}; + +bf_west = obj { + nam = "west", + dsc = "{На запад}", + act = function(s) + here().plX = here().plX - 1; + p("Вы идете на запад."); + here():make_turn(); + end; +}; + +bf_northwest = obj { + nam = "northwest", + dsc = "{На северо-запад}", + act = function(s) + here().plX = here().plX - 1; + here().plY = here().plY - 1; + p("Вы идете на северо-запад."); + here():make_turn(); + end; +}; + +bf_wait = obj { + nam = "wait", + dsc = "{Ждать}", + act = function(s) + p("Вы ждете"); + here():make_turn(); + end; +}; + +combatant = function(tab) + tab.canshoot = function(s) + local dist = here().getDistance(here().plX, here().plY, s.x, s.y); + return dist < 4 and not tab.ally; + end; + + tab.onshoot = function(s) + local dist = here().getDistance(here().plX, here().plY, s.x, s.y); + + if (rnd(4) > dist) then + if (dist == 0) then + tab.hp = tab.hp - 2; + end; + + tab.hp = tab.hp - 1; + if (tab.hp > 0) then + p(tab.shootHit); + else + p(tab.shootKill); + end; + else + p(tab.shootMiss); + end; + + here():make_turn(); + end; + + tab.canhit = function(s) + local dist = here().getDistance(here().plX, here().plY, s.x, s.y); + return dist == 0 and not tab.ally; + end; + + + tab.onhit = function(s) + local dist = here().getDistance(here().plX, here().plY, s.x, s.y); + if (dist == 0) then + tab.hp = tab.hp - 2; + if (tab.hp > 0) then + p(tab.wpnHit); + else + p(tab.wpnKill); + end; + + here():make_turn(); + else + p(tab.wpnFar); + end; + end; + + if (not tab.act) then + tab.act = function(s) + if tab.ally then + return tab.nohit; + end; + + local dist = here().getDistance(here().plX, here().plY, s.x, s.y); + + if (dist == 0) then + tab.hp = tab.hp - 1; + if (tab.hp > 0) then + p(tab.handHit); + else + p(tab.handKill); + end; + + here():make_turn(); + else + p(tab.handFar); + end; + end; + end; + if (not tab.make_turn) then + tab.make_turn = function(s) + end; + end; + + return obj(tab); +end; \ No newline at end of file