forked from github/server
commit
bec38f544b
|
@ -2768,6 +2768,24 @@ msgstr "\"$unit($unit) verspeiste $int($amount) Bauern.\""
|
|||
msgid "error320"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit kann nicht bewachen, da sie versucht zu fliehen.\""
|
||||
|
||||
msgid "error325"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Der Zauber kann nur auf ein einzelnes Schiff gewirkt werden.\""
|
||||
|
||||
msgid "error324"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit gehört nicht zu unserer Partei.\""
|
||||
|
||||
msgid "error322"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit ist bereits auf einem Schiff.\""
|
||||
|
||||
msgid "error323"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Das Schiff ist verzaubert.\""
|
||||
|
||||
msgid "error327"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - So viele Schiffe kann die Einheit nicht übergeben.\""
|
||||
|
||||
msgid "error326"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Diese Schiffe können keinen Konvoi bilden.\""
|
||||
|
||||
msgid "dissolve_units_2"
|
||||
msgstr "\"$unit($unit) in $region($region): $int($number) $race($race,$number) $if($eq($number,1),\"wurde zum Baum\", \"wurden zu Bäumen\").\""
|
||||
|
||||
|
|
|
@ -2768,6 +2768,24 @@ msgstr "\"$unit($unit) ate $int($amount) peasants.\""
|
|||
msgid "error320"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit cannot guard the region because it is trying to flee.\""
|
||||
|
||||
msgid "error325"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Spells can only be cast on a single ship.\""
|
||||
|
||||
msgid "error326"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - These ships cannot form a convoy.\""
|
||||
|
||||
msgid "error327"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit must keep at least one ship.\""
|
||||
|
||||
msgid "error324"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit is not one of ours.\""
|
||||
|
||||
msgid "error322"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit is already on a ship.\""
|
||||
|
||||
msgid "error323"
|
||||
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The ship is under a spell.\""
|
||||
|
||||
msgid "dissolve_units_2"
|
||||
msgstr "\"$unit($unit) in $region($region): $int($number) $race($race,$number) turned into $if($eq($number,1),\"a tree\", \"trees\").\""
|
||||
|
||||
|
|
|
@ -389,6 +389,9 @@ msgstr "Schaffenstrunk"
|
|||
msgid "balloon_a"
|
||||
msgstr "ein Ballon"
|
||||
|
||||
msgid "balloon_p"
|
||||
msgstr "Ballons"
|
||||
|
||||
msgid "undead_name_8"
|
||||
msgstr "Monster"
|
||||
|
||||
|
@ -1115,6 +1118,9 @@ msgstr "Orks"
|
|||
msgid "boat_a"
|
||||
msgstr "ein Boot"
|
||||
|
||||
msgid "boat_p"
|
||||
msgstr "Boote"
|
||||
|
||||
msgctxt "race"
|
||||
msgid "nymph"
|
||||
msgstr "Nymphe"
|
||||
|
@ -1719,9 +1725,15 @@ msgstr "Ring der Unsichtbarkeit"
|
|||
msgid "caravel_a"
|
||||
msgstr "eine Karavelle"
|
||||
|
||||
msgid "caravel_p"
|
||||
msgstr "Karavellen"
|
||||
|
||||
msgid "galleon_a"
|
||||
msgstr "eine Galeone"
|
||||
|
||||
msgid "galleon_p"
|
||||
msgstr "Galeonen"
|
||||
|
||||
msgctxt "keyword"
|
||||
msgid "describe"
|
||||
msgstr "BESCHREIBE"
|
||||
|
@ -1895,6 +1907,9 @@ msgstr "Untoten"
|
|||
msgid "flyingcarpet_a"
|
||||
msgstr "ein fliegender Teppich"
|
||||
|
||||
msgid "flyingcarpet_p"
|
||||
msgstr "fliegende Teppiche"
|
||||
|
||||
msgid "mallorntree_p"
|
||||
msgstr "Mallorn"
|
||||
|
||||
|
@ -2806,6 +2821,9 @@ msgstr "Fjordwuchs"
|
|||
msgid "trireme_a"
|
||||
msgstr "eine Trireme"
|
||||
|
||||
msgid "trireme_p"
|
||||
msgstr "Triremen"
|
||||
|
||||
msgctxt "prefix"
|
||||
msgid "Dunkel"
|
||||
msgstr "Dunkel"
|
||||
|
@ -4112,6 +4130,9 @@ msgstr "Luchs"
|
|||
msgid "longboat_a"
|
||||
msgstr "ein Langboot"
|
||||
|
||||
msgid "longboat_p"
|
||||
msgstr "Langboote"
|
||||
|
||||
msgctxt "race"
|
||||
msgid "human_d"
|
||||
msgstr "Menschen"
|
||||
|
@ -5858,6 +5879,9 @@ msgstr "Tiger"
|
|||
msgid "dragonship_a"
|
||||
msgstr "ein Drachenschiff"
|
||||
|
||||
msgid "dragonship_p"
|
||||
msgstr "Drachenschiffe"
|
||||
|
||||
msgctxt "race"
|
||||
msgid "mountainguard_x"
|
||||
msgstr "Bergwächter"
|
||||
|
|
|
@ -303,6 +303,9 @@ msgstr "busybeer"
|
|||
msgid "balloon_a"
|
||||
msgstr "a balloon"
|
||||
|
||||
msgid "balloon_p"
|
||||
msgstr "balloons"
|
||||
|
||||
msgid "jadee_ring"
|
||||
msgstr "Jadee's wedding ring"
|
||||
|
||||
|
@ -879,6 +882,9 @@ msgstr "gems"
|
|||
msgid "boat_a"
|
||||
msgstr "a boat"
|
||||
|
||||
msgid "boat_p"
|
||||
msgstr "boats"
|
||||
|
||||
msgctxt "race"
|
||||
msgid "orc_p"
|
||||
msgstr "orcs"
|
||||
|
@ -1458,12 +1464,18 @@ msgstr "ring of invisibility"
|
|||
msgid "galleon_a"
|
||||
msgstr "a galleon"
|
||||
|
||||
msgid "galleon_p"
|
||||
msgstr "galleons"
|
||||
|
||||
msgid "galleon"
|
||||
msgstr "galleon"
|
||||
|
||||
msgid "caravel_a"
|
||||
msgstr "a caravel"
|
||||
|
||||
msgid "caravel_p"
|
||||
msgstr "caravels"
|
||||
|
||||
msgid "mallornspear_p"
|
||||
msgstr "mallorn spear"
|
||||
|
||||
|
@ -2439,6 +2451,9 @@ msgstr "fjord fungus"
|
|||
msgid "trireme_a"
|
||||
msgstr "a trireme"
|
||||
|
||||
msgid "trireme_p"
|
||||
msgstr "triremes"
|
||||
|
||||
msgctxt "spell"
|
||||
msgid "healing"
|
||||
msgstr "Heal"
|
||||
|
@ -3639,6 +3654,9 @@ msgstr "goblin head"
|
|||
msgid "longboat_a"
|
||||
msgstr "a longboat"
|
||||
|
||||
msgid "longboat_p"
|
||||
msgstr "longboats"
|
||||
|
||||
msgctxt "race"
|
||||
msgid "lynx"
|
||||
msgstr "lynx"
|
||||
|
@ -5171,6 +5189,9 @@ msgstr "tiger"
|
|||
msgid "dragonship_a"
|
||||
msgstr "a dragonship"
|
||||
|
||||
msgid "dragonship_p"
|
||||
msgstr "dragonships"
|
||||
|
||||
msgctxt "race"
|
||||
msgid "mountainguard_x"
|
||||
msgstr "mountainguard"
|
||||
|
|
|
@ -75,3 +75,381 @@ function test_speedy_ship_fast()
|
|||
process_orders()
|
||||
assert_equal(8, u1.region.x)
|
||||
end
|
||||
|
||||
function test_ship_convoy_capacity()
|
||||
local r1 = region.create(1, 0, 'ocean')
|
||||
local r2 = region.create(2, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r1, 1)
|
||||
|
||||
u:add_order('NACH O')
|
||||
u:set_skill('sailing', 10, true)
|
||||
u:add_item('jewel', 490)
|
||||
u.ship = ship.create(r1, 'longboat')
|
||||
assert_equal(1, u.ship.number)
|
||||
process_orders()
|
||||
u:clear_orders()
|
||||
assert_equal(r2, u.region)
|
||||
|
||||
u:add_order('NACH W')
|
||||
u:add_item('jewel', 1)
|
||||
u:set_skill('sailing', 2, true)
|
||||
process_orders()
|
||||
u:clear_orders()
|
||||
assert_equal(r2, u.region) -- too heavy
|
||||
|
||||
u:add_order('NACH W')
|
||||
u:add_item('jewel', 489)
|
||||
u.ship.number = 2
|
||||
u.number = 2
|
||||
u:set_skill('sailing', 10, true)
|
||||
process_orders()
|
||||
u:clear_orders()
|
||||
assert_equal(r1, u.region) -- double capacity
|
||||
|
||||
u:add_order('NACH O')
|
||||
u.ship.number = 2
|
||||
u:add_item('jewel', 1) -- too heavy again
|
||||
process_orders()
|
||||
u:clear_orders()
|
||||
assert_equal(r1, u.region)
|
||||
end
|
||||
|
||||
function test_ship_convoy_crew()
|
||||
local r1 = region.create(1, 0, 'ocean')
|
||||
local r2 = region.create(2, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r1, 1)
|
||||
u.ship = ship.create(r1, 'longboat')
|
||||
u.ship.number = 2
|
||||
|
||||
u.number = 2
|
||||
u:set_skill('sailing', 5, true)
|
||||
u:add_order('NACH O')
|
||||
process_orders()
|
||||
u:clear_orders()
|
||||
assert_equal(r1, u.region) -- not enough captains
|
||||
|
||||
u:set_skill('sailing', 10, true)
|
||||
u:add_order('NACH O')
|
||||
process_orders()
|
||||
u:clear_orders()
|
||||
assert_equal(r2, u.region)
|
||||
end
|
||||
|
||||
function test_ship_convoy_skill()
|
||||
local r1 = region.create(1, 0, 'ocean')
|
||||
local r2 = region.create(2, 0, 'ocean')
|
||||
local r3 = region.create(3, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r1, 1)
|
||||
|
||||
u:set_skill('sailing', 10, true)
|
||||
u.ship = ship.create(r1, 'longboat')
|
||||
assert_equal(1, u.ship.number)
|
||||
u:add_order('NACH O')
|
||||
process_orders()
|
||||
assert_equal(r2, u.region)
|
||||
|
||||
u.ship.number = 2
|
||||
u:set_skill('sailing', 20, true)
|
||||
process_orders()
|
||||
assert_equal(r2, u.region) -- not enough captains
|
||||
|
||||
u.number = 2
|
||||
u:set_skill('sailing', 10, true)
|
||||
process_orders()
|
||||
assert_equal(r3, u.region)
|
||||
end
|
||||
|
||||
function test_give_ship()
|
||||
local r = region.create(1, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
u1.ship = ship.create(r, 'longboat')
|
||||
u1.ship.number = 2
|
||||
u1:add_order("GIB " .. itoa36(u2.id) .. " 1 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(1, u1.ship.number)
|
||||
assert_equal(1, u2.ship.number)
|
||||
end
|
||||
|
||||
function test_give_ship_new_unit()
|
||||
local r = region.create(1, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
u1.ship = ship.create(r, 'longboat')
|
||||
u1.ship.number = 2
|
||||
u1:add_order("GIB " .. itoa36(u2.id) .. " 1 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(1, u1.ship.number)
|
||||
assert_equal(1, u2.ship.number)
|
||||
end
|
||||
|
||||
function test_give_ship_same_ship()
|
||||
local r = region.create(1, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
u1.ship = ship.create(r, 'longboat')
|
||||
u2.ship = u1.ship
|
||||
u1.ship.number = 2
|
||||
u1:add_order("GIB " .. itoa36(u2.id) .. " 1 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(1, u1.ship.number)
|
||||
assert_equal(1, u2.ship.number)
|
||||
assert_not_equal(u1.ship, u2.ship)
|
||||
end
|
||||
|
||||
function test_give_ship_all_on_ocean()
|
||||
local r = region.create(0, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
u1.ship = ship.create(r, 'longboat')
|
||||
u1.ship.number = 2
|
||||
u1:add_order("GIB 0 2 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(2, u1.ship.number)
|
||||
end
|
||||
|
||||
function test_give_ship_all_on_land()
|
||||
local r = region.create(0, 0, 'plain')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
u1.ship = ship.create(r, 'longboat')
|
||||
u1.ship.number = 2
|
||||
u1:add_order("GIB 0 2 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(nil, u1.ship)
|
||||
assert_not_equal(nil, r.ships())
|
||||
end
|
||||
|
||||
function test_give_ship_no_boat()
|
||||
local r = region.create(1, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
u1.ship = ship.create(r, 'boat')
|
||||
u1.ship.number = 1
|
||||
u1:add_order("GIB " .. itoa36(u2.id) .. " 1 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(1, u1.ship.number)
|
||||
assert_equal(nil, u2.ship)
|
||||
end
|
||||
|
||||
function test_give_ship_away()
|
||||
local r = region.create(1, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
u1.ship = ship.create(r, 'longboat')
|
||||
u1.ship.number = 2
|
||||
u1:add_order("GIB 0 1 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(1, u1.ship.number)
|
||||
local count = 0
|
||||
for sh in r.ships do
|
||||
assert_equal(1, sh.number)
|
||||
count = count + 1
|
||||
end
|
||||
assert_equal(2, count)
|
||||
end
|
||||
|
||||
function test_give_ship_only_to_captain()
|
||||
local r = region.create(1, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
local u3 = unit.create(f, r, 1)
|
||||
u1.ship = ship.create(r, 'longboat')
|
||||
u1.ship.number = 2
|
||||
u2.ship = ship.create(r, 'longboat')
|
||||
u3.ship = u2.ship
|
||||
u1:add_order("GIB " .. itoa36(u3.id) .. " 1 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(2, u1.ship.number)
|
||||
assert_equal(1, u2.ship.number)
|
||||
end
|
||||
|
||||
function test_give_ship_compatible_coasts()
|
||||
local r = region.create(1, 0, 'plain')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
u1.ship = ship.create(r, 'longboat')
|
||||
u1.ship.number = 4
|
||||
u1:add_order("GIB " .. itoa36(u2.id) .. " 1 SCHIFF")
|
||||
u2.ship = ship.create(r, 'longboat')
|
||||
|
||||
-- cannot give a ship with different coast:
|
||||
u1.ship.coast = 1
|
||||
u2.ship.coast = 2
|
||||
process_orders()
|
||||
assert_equal(4, u1.ship.number)
|
||||
assert_equal(1, u2.ship.number)
|
||||
|
||||
-- can give a ship with no coast:
|
||||
u1.ship.coast = -1
|
||||
u2.ship.coast = 2
|
||||
process_orders()
|
||||
assert_equal(3, u1.ship.number)
|
||||
assert_equal(2, u2.ship.number)
|
||||
assert_equal(2, u2.ship.coast)
|
||||
|
||||
-- can give a ship with same coast:
|
||||
u1.ship.coast = 2
|
||||
u2.ship.coast = 2
|
||||
process_orders()
|
||||
assert_equal(2, u1.ship.number)
|
||||
assert_equal(3, u2.ship.number)
|
||||
assert_equal(2, u2.ship.coast)
|
||||
|
||||
-- giving to a ship with no coast:
|
||||
u1.ship.coast = 2
|
||||
u2.ship.coast = -1
|
||||
process_orders()
|
||||
assert_equal(1, u1.ship.number)
|
||||
assert_equal(4, u2.ship.number)
|
||||
assert_equal(2, u2.ship.coast)
|
||||
|
||||
end
|
||||
|
||||
function test_give_ship_only_from_captain()
|
||||
local r = region.create(1, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
local u3 = unit.create(f, r, 1)
|
||||
u2.ship = ship.create(r, 'longboat')
|
||||
u1.ship = ship.create(r, 'longboat')
|
||||
u1.ship.number = 2
|
||||
u3.ship = u1.ship
|
||||
u3:add_order("GIB " .. itoa36(u2.id) .. " 1 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(2, u1.ship.number)
|
||||
assert_equal(1, u2.ship.number)
|
||||
end
|
||||
|
||||
function test_give_ship_merge()
|
||||
local r = region.create(1, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
u2.ship = ship.create(r, 'longboat')
|
||||
u1.ship = ship.create(r, 'longboat')
|
||||
u1.ship.number = 2
|
||||
u1:add_order("GIB " .. itoa36(u2.id) .. " 1 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(1, u1.ship.number)
|
||||
assert_equal(2, u2.ship.number)
|
||||
end
|
||||
|
||||
function test_give_ship_only_same()
|
||||
local r = region.create(1, 0, 'ocean')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
u2.ship = ship.create(r, 'longboat')
|
||||
u1.ship = ship.create(r, 'caravel')
|
||||
u1.ship.number = 2
|
||||
u1:add_order("GIB " .. itoa36(u2.id) .. " 1 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(2, u1.ship.number)
|
||||
assert_equal(1, u2.ship.number)
|
||||
end
|
||||
|
||||
function test_give_ship_scale()
|
||||
local r = region.create(1, 0, 'plain')
|
||||
local f = faction.create("human")
|
||||
local u1 = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
local sh = ship.create(r, 'longboat')
|
||||
sh.number = 3
|
||||
sh.damage = 9
|
||||
sh.size = 12
|
||||
u1.ship = sh
|
||||
u1:add_order("GIB " .. itoa36(u2.id) .. " 2 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(1, u1.ship.number)
|
||||
assert_equal(3, u1.ship.damage)
|
||||
assert_equal(4, u1.ship.size)
|
||||
assert_equal(2, u2.ship.number)
|
||||
assert_equal(6, u2.ship.damage)
|
||||
assert_equal(8, u2.ship.size)
|
||||
end
|
||||
|
||||
function test_give_ship_all_ships()
|
||||
local r = region.create(1, 0, 'plain')
|
||||
local f = faction.create("human", 'noreply@vg.no')
|
||||
local u1 = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
u1.ship = ship.create(r, 'longboat')
|
||||
u1.ship.damage = 2
|
||||
u1.ship.number = 2
|
||||
u2.ship = ship.create(r, 'longboat')
|
||||
u2.ship.number = 1
|
||||
u1:add_order("GIB " .. itoa36(u2.id) .. " 2 SCHIFF")
|
||||
process_orders()
|
||||
write_reports()
|
||||
assert_equal(3, u2.ship.number)
|
||||
assert_equal(u2.ship, u1.ship)
|
||||
end
|
||||
|
||||
function test_give_ship_self_only()
|
||||
local r = region.create(1, 0, 'plain')
|
||||
local f1 = faction.create("human")
|
||||
local f2 = faction.create("human")
|
||||
local u1 = unit.create(f1, r, 1)
|
||||
local u2 = unit.create(f2, r, 1)
|
||||
local sh = ship.create(r, 'longboat')
|
||||
sh.number = 2
|
||||
u1.ship = sh
|
||||
u1:add_order("GIB " .. itoa36(u2.id) .. " 1 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(2, u1.ship.number)
|
||||
assert_equal(nil, u2.ship)
|
||||
end
|
||||
|
||||
function test_give_ship_not_cursed()
|
||||
local r = region.create(1, 0, 'plain')
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r, 1)
|
||||
local u2 = unit.create(f, r, 1)
|
||||
local sh = ship.create(r, 'longboat')
|
||||
u.ship = sh
|
||||
u:add_item("speedsail", 1)
|
||||
u:add_order("BENUTZE 1 Sonnensegel")
|
||||
process_orders()
|
||||
u:clear_orders()
|
||||
assert_equal(1, sh:get_curse('shipspeedup'))
|
||||
|
||||
u:add_order("GIB " .. itoa36(u2.id) .. " 1 SCHIFF")
|
||||
process_orders()
|
||||
assert_equal(nil, u2.ship)
|
||||
end
|
||||
|
||||
function test_speedsail_on_ship()
|
||||
local r = region.create(1, 0, 'plain')
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r, 1)
|
||||
local sh = ship.create(r, 'longboat')
|
||||
u.ship = sh
|
||||
u:add_item("speedsail", 1)
|
||||
u:add_order("BENUTZE 1 Sonnensegel")
|
||||
process_orders()
|
||||
assert_equal(1, sh:get_curse('shipspeedup'))
|
||||
end
|
||||
|
||||
function test_no_speedsail_on_convoy()
|
||||
local r = region.create(1, 0, 'plain')
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r, 1)
|
||||
local sh = ship.create(r, 'longboat')
|
||||
u.ship = sh
|
||||
sh.number = 2
|
||||
u:add_item("speedsail", 2)
|
||||
u:add_order("BENUTZE 2 Sonnensegel")
|
||||
process_orders()
|
||||
assert_equal(nil, sh:get_curse('shipspeedup'))
|
||||
end
|
||||
|
|
110
src/bind_ship.c
110
src/bind_ship.c
|
@ -38,39 +38,54 @@ int tolua_shiplist_next(lua_State * L)
|
|||
return 0; /* no more values to return */
|
||||
}
|
||||
|
||||
static int tolua_ship_get_number(lua_State * L)
|
||||
{
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, sh->number);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_number(lua_State * L)
|
||||
{
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
int n = (int)tolua_tonumber(L, 2, 0);
|
||||
scale_ship(sh, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_id(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, self->no);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, sh->no);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_name(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
tolua_pushstring(L, ship_getname(self));
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
tolua_pushstring(L, ship_getname(sh));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_size(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, self->size);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, sh->size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_display(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
tolua_pushstring(L, self->display);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
tolua_pushstring(L, sh->display);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_region(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
if (self) {
|
||||
tolua_pushusertype(L, self->region, TOLUA_CAST "region");
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
if (sh) {
|
||||
tolua_pushusertype(L, sh->region, TOLUA_CAST "region");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -78,43 +93,43 @@ static int tolua_ship_get_region(lua_State * L)
|
|||
|
||||
static int tolua_ship_set_region(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
region *r = (region *)tolua_tousertype(L, 2, NULL);
|
||||
if (self) {
|
||||
move_ship(self, self->region, r, NULL);
|
||||
if (sh) {
|
||||
move_ship(sh, sh->region, r, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_name(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
ship_setname(self, tolua_tostring(L, 2, NULL));
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
ship_setname(sh, tolua_tostring(L, 2, NULL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_size(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
self->size = lua_tointeger(L, 2);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
sh->size = lua_tointeger(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_display(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
free(self->display);
|
||||
self->display = str_strdup(tolua_tostring(L, 2, NULL));
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
free(sh->display);
|
||||
sh->display = str_strdup(tolua_tostring(L, 2, NULL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_units(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
unit **unit_ptr = (unit **)lua_newuserdata(L, sizeof(unit *));
|
||||
unit *u = self->region->units;
|
||||
unit *u = sh->region->units;
|
||||
|
||||
while (u && u->ship != self)
|
||||
while (u && u->ship != sh)
|
||||
u = u->next;
|
||||
luaL_getmetatable(L, TOLUA_CAST "unit");
|
||||
lua_setmetatable(L, -2);
|
||||
|
@ -147,42 +162,42 @@ static int tolua_ship_create(lua_State * L)
|
|||
static int
|
||||
tolua_ship_tostring(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushstring(L, shipname(self));
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushstring(L, shipname(sh));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_flags(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, self->flags);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, sh->flags);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_flags(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
self->flags = (int)lua_tointeger(L, 2);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
sh->flags = (int)lua_tointeger(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_coast(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
if (lua_isnil(L, 2)) {
|
||||
self->coast = NODIRECTION;
|
||||
sh->coast = NODIRECTION;
|
||||
}
|
||||
else if (lua_isnumber(L, 2)) {
|
||||
self->coast = (direction_t)lua_tointeger(L, 2);
|
||||
sh->coast = (direction_t)lua_tointeger(L, 2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_coast(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
if (self->coast) {
|
||||
lua_pushinteger(L, self->coast);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
if (sh->coast) {
|
||||
lua_pushinteger(L, sh->coast);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -190,30 +205,30 @@ static int tolua_ship_get_coast(lua_State * L)
|
|||
|
||||
static int tolua_ship_get_type(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
tolua_pushstring(L, self->type->_name);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
tolua_pushstring(L, sh->type->_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_damage(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, self->damage);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, sh->damage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_damage(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
self->damage = (int)lua_tointeger(L, 2);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
sh->damage = (int)lua_tointeger(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_curse(lua_State *L) {
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
const char *name = tolua_tostring(L, 2, NULL);
|
||||
if (self->attribs) {
|
||||
curse * c = get_curse(self->attribs, ct_find(name));
|
||||
if (sh->attribs) {
|
||||
curse * c = get_curse(sh->attribs, ct_find(name));
|
||||
if (c) {
|
||||
lua_pushnumber(L, curse_geteffect(c));
|
||||
return 1;
|
||||
|
@ -223,9 +238,9 @@ static int tolua_ship_get_curse(lua_State *L) {
|
|||
}
|
||||
|
||||
static int tolua_ship_has_attrib(lua_State *L) {
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
ship *sh = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
const char *name = tolua_tostring(L, 2, NULL);
|
||||
attrib * a = a_find(self->attribs, at_find(name));
|
||||
attrib * a = a_find(sh->attribs, at_find(name));
|
||||
lua_pushboolean(L, a != NULL);
|
||||
return 1;
|
||||
}
|
||||
|
@ -243,6 +258,7 @@ void tolua_ship_open(lua_State * L)
|
|||
{
|
||||
tolua_function(L, TOLUA_CAST "__tostring", tolua_ship_tostring);
|
||||
tolua_variable(L, TOLUA_CAST "id", tolua_ship_get_id, NULL);
|
||||
tolua_variable(L, TOLUA_CAST "number", tolua_ship_get_number, tolua_ship_set_number);
|
||||
tolua_variable(L, TOLUA_CAST "name", tolua_ship_get_name,
|
||||
tolua_ship_set_name);
|
||||
tolua_variable(L, TOLUA_CAST "size", tolua_ship_get_size,
|
||||
|
|
|
@ -884,9 +884,19 @@ static int tolua_unit_create(lua_State * L)
|
|||
const char *rcname = tolua_tostring(L, 4, NULL);
|
||||
const race *rc;
|
||||
|
||||
assert(f && r);
|
||||
if (!r) {
|
||||
log_warning("unit.create: arg(2) is not a region");
|
||||
return 0;
|
||||
}
|
||||
if (!f) {
|
||||
log_warning("unit.create: arg(1) is not a faction");
|
||||
return 0;
|
||||
}
|
||||
rc = rcname ? rc_find(rcname) : f->race;
|
||||
assert(rc);
|
||||
if (!rc) {
|
||||
log_warning("unit.create: unknown race %s", rcname);
|
||||
return 0;
|
||||
}
|
||||
u = create_unit(r, f, num, rc, 0, NULL, NULL);
|
||||
tolua_pushusertype(L, u, TOLUA_CAST "unit");
|
||||
return 1;
|
||||
|
|
|
@ -84,7 +84,7 @@ static char g_bigbuf[BUFFERSIZE];
|
|||
bool opt_cr_absolute_coords = false;
|
||||
|
||||
/* globals */
|
||||
#define C_REPORT_VERSION 66
|
||||
#define C_REPORT_VERSION 67
|
||||
|
||||
struct locale *crtag_locale(void) {
|
||||
static struct locale * lang;
|
||||
|
@ -515,8 +515,10 @@ static void report_crtypes(FILE * F, const struct locale *lang)
|
|||
fputc('\"', F);
|
||||
fputs(crescape(nrt_string(kmt->mtype, lang), buffer, sizeof(buffer)), F);
|
||||
fputs("\";text\n", F);
|
||||
if (kmt->mtype->section) {
|
||||
fprintf(F, "\"%s\";section\n", kmt->mtype->section);
|
||||
}
|
||||
}
|
||||
while (mtypehash[i]) {
|
||||
kmt = mtypehash[i];
|
||||
mtypehash[i] = mtypehash[i]->nexthash;
|
||||
|
@ -695,6 +697,7 @@ static void cr_output_ship(struct stream *out, const ship *sh, const unit *u,
|
|||
stream_printf(out, "\"%s\";Beschr\n", sh->display);
|
||||
stream_printf(out, "\"%s\";Typ\n", translate(sh->type->_name,
|
||||
LOC(f->locale, sh->type->_name)));
|
||||
stream_printf(out, "%d;Anzahl\n", sh->number);
|
||||
stream_printf(out, "%d;Groesse\n", sh->size);
|
||||
if (sh->damage) {
|
||||
int percent =
|
||||
|
@ -710,7 +713,7 @@ static void cr_output_ship(struct stream *out, const ship *sh, const unit *u,
|
|||
/* calculate cargo */
|
||||
if (u && (u->faction == f || omniscient(f))) {
|
||||
int n = 0, p = 0;
|
||||
int mweight = shipcapacity(sh);
|
||||
int mweight = ship_capacity(sh);
|
||||
getshipweight(sh, &n, &p);
|
||||
|
||||
stream_printf(out, "%d;capacity\n", mweight);
|
||||
|
|
133
src/give.c
133
src/give.c
|
@ -293,6 +293,117 @@ bool rule_transfermen(void)
|
|||
return rule != 0;
|
||||
}
|
||||
|
||||
static void transfer_ships(ship *s1, ship *s2, int n)
|
||||
{
|
||||
assert(n <= s1->number);
|
||||
s2->damage += s1->damage * n / s1->number;
|
||||
s2->size += s1->size * n / s1->number;
|
||||
s2->number += n;
|
||||
if (s1->coast != NODIRECTION) {
|
||||
s2->coast = s1->coast;
|
||||
}
|
||||
scale_ship(s1, s1->number - n);
|
||||
}
|
||||
|
||||
static void transfer_units(ship *s1, ship *s2)
|
||||
{
|
||||
region * r = s1->region;
|
||||
unit *u;
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->ship == s1) {
|
||||
leave_ship(u);
|
||||
u_set_ship(u, s2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool ship_cursed(const ship *sh) {
|
||||
return a_find(sh->attribs, &at_curse) != NULL;
|
||||
}
|
||||
|
||||
message * give_ship(unit *u1, unit *u2, int n, order *ord)
|
||||
{
|
||||
assert(u1->ship);
|
||||
assert(n > 0 && n <= u1->ship->number);
|
||||
if (u1->ship->type->range < 3) {
|
||||
/* Keine Boote und anderes Kleinzeug erlaubt */
|
||||
return msg_error(u1, ord, 326);
|
||||
}
|
||||
if (ship_cursed(u1->ship)) {
|
||||
return msg_error(u1, ord, 323);
|
||||
}
|
||||
if (u1 != ship_owner(u1->ship)) {
|
||||
return msg_error(u1, ord, 146);
|
||||
}
|
||||
if (u2 == NULL) {
|
||||
if (fval(u1->region->terrain, LAND_REGION) || n < u1->ship->number) {
|
||||
ship * sh = new_ship(u1->ship->type, u1->region, u1->faction->locale);
|
||||
scale_ship(sh, 0);
|
||||
transfer_ships(u1->ship, sh, n);
|
||||
}
|
||||
else {
|
||||
return msg_error(u1, ord, 327);
|
||||
}
|
||||
} else {
|
||||
if (u1->faction != u2->faction) {
|
||||
return msg_error(u1, ord, 324);
|
||||
}
|
||||
if (fval(u_race(u2), RCF_CANSAIL)) {
|
||||
if (u2->ship) {
|
||||
if (u2->ship == u1->ship) {
|
||||
ship * sh = new_ship(u1->ship->type, u1->region, u1->faction->locale);
|
||||
scale_ship(sh, 0);
|
||||
leave_ship(u2);
|
||||
u_set_ship(u2, sh);
|
||||
} else {
|
||||
if (u2 != ship_owner(u2->ship)) {
|
||||
return msg_error(u1, ord, 146);
|
||||
}
|
||||
if (u2->ship->type != u1->ship->type) {
|
||||
return msg_error(u1, ord, 322);
|
||||
}
|
||||
if (ship_cursed(u2->ship)) {
|
||||
return msg_error(u1, ord, 323);
|
||||
}
|
||||
if (u1->ship->coast != u2->ship->coast) {
|
||||
if (u1->ship->coast != NODIRECTION) {
|
||||
if (u2->ship->coast == NODIRECTION) {
|
||||
u2->ship->coast = u1->ship->coast;
|
||||
}
|
||||
else {
|
||||
return msg_error(u1, ord, 182);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n < u1->ship->number) {
|
||||
transfer_ships(u1->ship, u2->ship, n);
|
||||
}
|
||||
else {
|
||||
transfer_ships(u1->ship, u2->ship, n);
|
||||
transfer_units(u1->ship, u2->ship);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (n < u1->ship->number) {
|
||||
ship * sh = new_ship(u1->ship->type, u1->region, u1->faction->locale);
|
||||
scale_ship(sh, 0);
|
||||
u_set_ship(u2, sh);
|
||||
transfer_ships(u1->ship, sh, n);
|
||||
}
|
||||
else {
|
||||
u_set_ship(u2, u1->ship);
|
||||
ship_set_owner(u2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return msg_error(u1, ord, 233);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
message * give_men(int n, unit * u, unit * u2, struct order *ord)
|
||||
{
|
||||
int error = 0;
|
||||
|
@ -652,7 +763,8 @@ static void give_all_items(unit *u, unit *u2, order *ord) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (isparam(s, u->faction->locale, P_PERSON)) {
|
||||
param_t p = findparam(s, u->faction->locale);
|
||||
if (p == P_PERSON) {
|
||||
if (!(u_race(u)->ec_flags & ECF_GIVEPERSON)) {
|
||||
ADDMSG(&u->faction->msgs,
|
||||
msg_feedback(u, ord, "race_noregroup", "race", u_race(u)));
|
||||
|
@ -815,7 +927,24 @@ void give_cmd(unit * u, order * ord)
|
|||
return;
|
||||
}
|
||||
|
||||
if (isparam(s, u->faction->locale, P_PERSON)) {
|
||||
p = findparam(s, u->faction->locale);
|
||||
if (p == P_SHIP) {
|
||||
if (u->ship) {
|
||||
message * msg;
|
||||
if (n > u->ship->number) {
|
||||
n = u->ship->number;
|
||||
}
|
||||
msg = give_ship(u, u2, n, ord);
|
||||
if (msg) {
|
||||
ADDMSG(&u->faction->msgs, msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
cmistake(u, ord, 144, MSG_COMMERCE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (p == P_PERSON) {
|
||||
if (!(u_race(u)->ec_flags & ECF_GIVEPERSON)) {
|
||||
ADDMSG(&u->faction->msgs,
|
||||
msg_feedback(u, ord, "race_noregroup", "race", u_race(u)));
|
||||
|
|
|
@ -101,6 +101,10 @@ struct order *ord)
|
|||
cmistake(u, ord, 20, MSG_MOVE);
|
||||
return -1;
|
||||
}
|
||||
if (sh->number > 1) {
|
||||
cmistake(u, ord, 325, MSG_MAGIC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
effect = SPEEDSAIL_EFFECT;
|
||||
create_curse(u, &sh->attribs, &ct_shipspeedup, 20, INT_MAX, effect, 0);
|
||||
|
|
|
@ -932,8 +932,7 @@ static void build_ship(unit * u, ship * sh, int want)
|
|||
msg_message("buildship", "ship unit size", sh, u, n));
|
||||
}
|
||||
|
||||
void
|
||||
create_ship(unit * u, const struct ship_type *newtype, int want,
|
||||
void create_ship(unit * u, const struct ship_type *newtype, int want,
|
||||
order * ord)
|
||||
{
|
||||
ship *sh;
|
||||
|
|
|
@ -45,8 +45,9 @@
|
|||
#define FIX_RES_BASE_VERSION 367 /* fixing resource base */
|
||||
#define FIX_CLONES_VERSION 368 /* dissolve clones */
|
||||
#define FIX_MIGRANT_AURA_VERSION 369 /* bug 2585, migrants with aura */
|
||||
#define SHIP_NUMBER_VERISON 370 /* ships have a number */
|
||||
|
||||
#define RELEASE_VERSION FIX_MIGRANT_AURA_VERSION /* current datafile */
|
||||
#define RELEASE_VERSION SHIP_NUMBER_VERISON /* current datafile */
|
||||
#define MIN_VERSION UIDHASH_VERSION /* minimal datafile we support */
|
||||
#define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */
|
||||
|
||||
|
|
|
@ -1283,6 +1283,8 @@ void write_ship(gamedata *data, const ship *sh)
|
|||
WRITE_STR(store, (const char *)sh->name);
|
||||
WRITE_STR(store, sh->display ? (const char *)sh->display : "");
|
||||
WRITE_TOK(store, sh->type->_name);
|
||||
assert(sh->number > 0);
|
||||
WRITE_INT(store, sh->number);
|
||||
WRITE_INT(store, sh->size);
|
||||
WRITE_INT(store, sh->damage);
|
||||
WRITE_INT(store, sh->flags & SFL_SAVEMASK);
|
||||
|
@ -1320,6 +1322,12 @@ ship *read_ship(gamedata *data)
|
|||
}
|
||||
assert(sh->type || !"ship_type not registered!");
|
||||
|
||||
if (data->version < SHIP_NUMBER_VERISON) {
|
||||
sh->number = 1;
|
||||
}
|
||||
else {
|
||||
READ_INT(store, &sh->number);
|
||||
}
|
||||
READ_INT(store, &sh->size);
|
||||
READ_INT(store, &sh->damage);
|
||||
if (data->version >= FOSS_VERSION) {
|
||||
|
|
|
@ -181,6 +181,7 @@ ship *new_ship(const ship_type * stype, region * r, const struct locale *lang)
|
|||
sh->coast = NODIRECTION;
|
||||
sh->type = stype;
|
||||
sh->region = r;
|
||||
sh->number = 1;
|
||||
|
||||
if (lang) {
|
||||
sname = LOC(lang, stype->_name);
|
||||
|
@ -275,13 +276,13 @@ static int ShipSpeedBonus(const unit * u)
|
|||
}
|
||||
if (bonus > 0) {
|
||||
int skl = effskill(u, SK_SAILING, NULL);
|
||||
int minsk = (sh->type->cptskill + 1) / 2;
|
||||
int minsk = (ship_captain_minskill(sh) + 1) / 2;
|
||||
return (skl - minsk) / bonus;
|
||||
}
|
||||
else if (sh->type->flags & SFL_SPEEDY) {
|
||||
int base = 3;
|
||||
int speed = 0;
|
||||
int minsk = sh->type->cptskill * base;
|
||||
int minsk = ship_captain_minskill(sh) * base;
|
||||
int skl = effskill(u, SK_SAILING, NULL);
|
||||
while (skl >= minsk) {
|
||||
++speed;
|
||||
|
@ -292,21 +293,8 @@ static int ShipSpeedBonus(const unit * u)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int crew_skill(const ship *sh) {
|
||||
int n = 0;
|
||||
unit *u;
|
||||
|
||||
n = 0;
|
||||
|
||||
for (u = sh->region->units; u; u = u->next) {
|
||||
if (u->ship == sh) {
|
||||
int es = effskill(u, SK_SAILING, NULL);
|
||||
if (es >= sh->type->minskill) {
|
||||
n += es * u->number;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
int ship_captain_minskill(const ship *sh) {
|
||||
return sh->type->cptskill;
|
||||
}
|
||||
|
||||
int shipspeed(const ship * sh, const unit * u)
|
||||
|
@ -323,9 +311,9 @@ int shipspeed(const ship * sh, const unit * u)
|
|||
assert(sh->type->construction);
|
||||
|
||||
k = sh->type->range;
|
||||
if (sh->size != sh->type->construction->maxsize)
|
||||
if (!ship_finished(sh)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
if (sh->attribs) {
|
||||
if (curse_active(get_curse(sh->attribs, &ct_stormwind))) {
|
||||
k *= 2;
|
||||
|
@ -385,17 +373,85 @@ const char *shipname(const ship * sh)
|
|||
return write_shipname(sh, ibuf, sizeof(idbuf[0]));
|
||||
}
|
||||
|
||||
int shipcapacity(const ship * sh)
|
||||
bool ship_finished(const ship *sh)
|
||||
{
|
||||
int i = sh->type->cargo;
|
||||
if (sh->type->construction) {
|
||||
return (sh->size >= sh->number * sh->type->construction->maxsize);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sh->type->construction && sh->size != sh->type->construction->maxsize)
|
||||
return 0;
|
||||
int enoughsailors(const ship * sh, int crew_skill)
|
||||
{
|
||||
return crew_skill >= sh->type->sumskill * sh->number;
|
||||
}
|
||||
|
||||
int crew_skill(const ship *sh) {
|
||||
int n = 0;
|
||||
unit *u;
|
||||
|
||||
for (u = sh->region->units; u; u = u->next) {
|
||||
if (u->ship == sh) {
|
||||
int es = effskill(u, SK_SAILING, NULL);
|
||||
if (es >= sh->type->minskill) {
|
||||
n += es * u->number;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
bool ship_crewed(const ship *sh) {
|
||||
unit *u;
|
||||
int capskill = -1, sumskill = 0;
|
||||
for (u = sh->region->units; u; u = u->next) {
|
||||
if (u->ship == sh) {
|
||||
int es = effskill(u, SK_SAILING, NULL);
|
||||
if (capskill < 0) {
|
||||
if (u->number >= sh->number) {
|
||||
capskill = es;
|
||||
}
|
||||
else {
|
||||
capskill = 0;
|
||||
}
|
||||
}
|
||||
if (es >= sh->type->minskill) {
|
||||
sumskill += es * u->number;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (capskill >= ship_captain_minskill(sh)) && (sumskill >= sh->type->sumskill * sh->number);
|
||||
}
|
||||
|
||||
void scale_ship(ship *sh, int n)
|
||||
{
|
||||
sh->size = sh->size * n / sh->number;
|
||||
sh->damage = sh->damage * n / sh->number;
|
||||
sh->number = n;
|
||||
}
|
||||
|
||||
int ship_capacity(const ship * sh)
|
||||
{
|
||||
if (ship_finished(sh)) {
|
||||
int i = sh->type->cargo * sh->number;
|
||||
if (sh->damage) {
|
||||
i = (int)ceil(i * (1.0 - sh->damage / sh->size / (double)DAMAGE_SCALE));
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ship_cabins(const ship * sh)
|
||||
{
|
||||
if (ship_finished(sh)) {
|
||||
int i = sh->type->cabins * sh->number;
|
||||
if (sh->damage) {
|
||||
i = (int)ceil(i * (1.0 - sh->damage / sh->size / (double)DAMAGE_SCALE));
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void getshipweight(const ship * sh, int *sweight, int *scabins)
|
||||
|
@ -465,17 +521,17 @@ void write_ship_reference(const struct ship *sh, struct storage *store)
|
|||
WRITE_INT(store, (sh && sh->region) ? sh->no : 0);
|
||||
}
|
||||
|
||||
void ship_setname(ship * self, const char *name)
|
||||
void ship_setname(ship * sh, const char *name)
|
||||
{
|
||||
free(self->name);
|
||||
self->name = name ? str_strdup(name) : 0;
|
||||
free(sh->name);
|
||||
sh->name = name ? str_strdup(name) : 0;
|
||||
}
|
||||
|
||||
const char *ship_getname(const ship * self)
|
||||
const char *ship_getname(const ship * sh)
|
||||
{
|
||||
return self->name;
|
||||
return sh->name;
|
||||
}
|
||||
|
||||
int ship_damage_percent(const ship *ship) {
|
||||
return (ship->damage * 100 + DAMAGE_SCALE - 1) / (ship->size * DAMAGE_SCALE);
|
||||
int ship_damage_percent(const ship *sh) {
|
||||
return (sh->damage * 100 + DAMAGE_SCALE - 1) / (sh->size * DAMAGE_SCALE);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ extern "C" {
|
|||
struct ship *nexthash;
|
||||
struct unit * _owner; /* never use directly, always use ship_owner() */
|
||||
int no;
|
||||
int number;
|
||||
struct region *region;
|
||||
char *name;
|
||||
char *display;
|
||||
|
@ -89,8 +90,10 @@ extern "C" {
|
|||
struct unit *ship_owner(const struct ship *sh);
|
||||
void ship_update_owner(struct ship * sh);
|
||||
|
||||
extern const char *shipname(const struct ship *self);
|
||||
extern int shipcapacity(const struct ship *sh);
|
||||
const char *shipname(const struct ship *self);
|
||||
int ship_capacity(const struct ship *sh);
|
||||
int ship_cabins(const struct ship *sh);
|
||||
bool ship_finished(const struct ship *sh);
|
||||
extern void getshipweight(const struct ship *sh, int *weight, int *cabins);
|
||||
|
||||
extern ship *new_ship(const struct ship_type *stype, struct region *r,
|
||||
|
@ -113,9 +116,13 @@ extern "C" {
|
|||
const char *ship_getname(const struct ship *sh);
|
||||
void ship_setname(struct ship *self, const char *name);
|
||||
int shipspeed(const struct ship *sh, const struct unit *u);
|
||||
|
||||
bool ship_crewed(const struct ship *sh);
|
||||
int crew_skill(const struct ship *sh);
|
||||
int ship_captain_minskill(const struct ship *sh);
|
||||
|
||||
int ship_damage_percent(const struct ship *sh);
|
||||
void scale_ship(struct ship *sh, int n);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1094,8 +1094,8 @@ int enter_ship(unit * u, struct order *ord, int id, bool report)
|
|||
}
|
||||
if (CheckOverload()) {
|
||||
int sweight, scabins;
|
||||
int mweight = shipcapacity(sh);
|
||||
int mcabins = sh->type->cabins;
|
||||
int mweight = ship_capacity(sh);
|
||||
int mcabins = ship_cabins(sh);
|
||||
|
||||
if (mweight > 0) {
|
||||
getshipweight(sh, &sweight, &scabins);
|
||||
|
@ -2598,7 +2598,7 @@ void sinkships(struct region * r)
|
|||
|
||||
if (!sh->type->construction || sh->size >= sh->type->construction->maxsize) {
|
||||
if (fval(r->terrain, SEA_REGION)) {
|
||||
if (!enoughsailors(sh, crew_skill(sh))) {
|
||||
if (!ship_crewed(sh)) {
|
||||
/* ship is at sea, but not enough people to control it */
|
||||
double dmg = config_get_flt("rules.ship.damage.nocrewocean", 0.3);
|
||||
damage_ship(sh, dmg);
|
||||
|
|
35
src/move.c
35
src/move.c
|
@ -470,13 +470,13 @@ static bool cansail(const region * r, ship * sh)
|
|||
{
|
||||
UNUSED_ARG(r);
|
||||
|
||||
if (sh->type->construction && sh->size != sh->type->construction->maxsize) {
|
||||
if (!ship_finished(sh)) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
int n = 0, p = 0;
|
||||
int mweight = shipcapacity(sh);
|
||||
int mcabins = sh->type->cabins;
|
||||
int mweight = ship_capacity(sh);
|
||||
int mcabins = ship_cabins(sh);
|
||||
|
||||
getshipweight(sh, &n, &p);
|
||||
|
||||
|
@ -492,12 +492,12 @@ static double overload(const region * r, ship * sh)
|
|||
{
|
||||
UNUSED_ARG(r);
|
||||
|
||||
if (sh->type->construction && sh->size != sh->type->construction->maxsize) {
|
||||
if (!ship_finished(sh)) {
|
||||
return DBL_MAX;
|
||||
}
|
||||
else {
|
||||
int n = 0, p = 0;
|
||||
int mcabins = sh->type->cabins;
|
||||
int mcabins = sh->type->cabins * sh->number;
|
||||
double ovl;
|
||||
|
||||
getshipweight(sh, &n, &p);
|
||||
|
@ -509,11 +509,6 @@ static double overload(const region * r, ship * sh)
|
|||
}
|
||||
}
|
||||
|
||||
int enoughsailors(const ship * sh, int crew_skill)
|
||||
{
|
||||
return crew_skill >= sh->type->sumskill;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
static ship *do_maelstrom(region * r, unit * u)
|
||||
|
@ -808,7 +803,7 @@ static void drifting_ships(region * r)
|
|||
ship *sh = *shp;
|
||||
region *rnext = NULL;
|
||||
region_list *route = NULL;
|
||||
unit *firstu = r->units, *lastu = NULL, *captain;
|
||||
unit *firstu = r->units, *lastu = NULL;
|
||||
direction_t dir = NODIRECTION;
|
||||
double ovl;
|
||||
|
||||
|
@ -822,16 +817,10 @@ static void drifting_ships(region * r)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Kapitaen bestimmen */
|
||||
captain = ship_owner(sh);
|
||||
if (captain && effskill(captain, SK_SAILING, r) < sh->type->cptskill)
|
||||
captain = NULL;
|
||||
|
||||
/* Kapitaen da? Beschaedigt? Genuegend Matrosen?
|
||||
* Genuegend leicht? Dann ist alles OK. */
|
||||
|
||||
if (captain && sh->size == sh->type->construction->maxsize
|
||||
&& enoughsailors(sh, crew_skill(sh)) && cansail(r, sh)) {
|
||||
if (ship_finished(sh) && ship_crewed(sh) && cansail(r, sh)) {
|
||||
shp = &sh->next;
|
||||
continue;
|
||||
}
|
||||
|
@ -1639,19 +1628,17 @@ static bool ship_ready(const region * r, unit * u, order * ord)
|
|||
cmistake(u, ord, 146, MSG_MOVE);
|
||||
return false;
|
||||
}
|
||||
if (effskill(u, SK_SAILING, r) < u->ship->type->cptskill) {
|
||||
if (effskill(u, SK_SAILING, r) < ship_captain_minskill(u->ship)) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord,
|
||||
"error_captain_skill_low", "value ship", u->ship->type->cptskill,
|
||||
"error_captain_skill_low", "value ship", ship_captain_minskill(u->ship),
|
||||
u->ship));
|
||||
return false;
|
||||
}
|
||||
if (u->ship->type->construction) {
|
||||
if (u->ship->size != u->ship->type->construction->maxsize) {
|
||||
if (!ship_finished(u->ship)) {
|
||||
cmistake(u, ord, 15, MSG_MOVE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!enoughsailors(u->ship, crew_skill(u->ship))) {
|
||||
if (!ship_crewed(u->ship)) {
|
||||
cmistake(u, ord, 1, MSG_MOVE);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ extern "C" {
|
|||
|
||||
int personcapacity(const struct unit *u);
|
||||
void movement(void);
|
||||
void run_to(struct unit *u, struct region *to);
|
||||
int enoughsailors(const struct ship *sh, int sumskill);
|
||||
bool canswim(struct unit *u);
|
||||
bool canfly(struct unit *u);
|
||||
|
|
|
@ -1724,11 +1724,14 @@ nr_ship(struct stream *out, const region *r, const ship * sh, const faction * f,
|
|||
|
||||
if (captain && captain->faction == f) {
|
||||
int n = 0, p = 0;
|
||||
const char *stname;
|
||||
|
||||
getshipweight(sh, &n, &p);
|
||||
n = (n + 99) / 100; /* 1 Silber = 1 GE */
|
||||
|
||||
sbs_printf(&sbs, "%s, %s, (%d/%d)", shipname(sh),
|
||||
LOC(f->locale, sh->type->_name), n, shipcapacity(sh) / 100);
|
||||
stname = locale_plural(f->locale, sh->type->_name, sh->number, true);
|
||||
sbs_printf(&sbs, "%s, %d %s, (%d/%d)", shipname(sh), sh->number,
|
||||
stname, n, ship_capacity(sh) / 100);
|
||||
}
|
||||
else {
|
||||
sbs_printf(&sbs, "%s, %s", shipname(sh), LOC(f->locale, sh->type->_name));
|
||||
|
|
|
@ -808,6 +808,10 @@ static int sp_goodwinds(castorder * co)
|
|||
return 0;
|
||||
|
||||
sh = pa->param[0]->data.sh;
|
||||
if (sh->number > 1) {
|
||||
cmistake(caster, co->order, 325, MSG_MAGIC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* keine Probleme mit C_SHIP_SPEEDUP und C_SHIP_FLYING */
|
||||
/* NODRIFT bewirkt auch +1 Geschwindigkeit */
|
||||
|
@ -2231,6 +2235,10 @@ static int sp_stormwinds(castorder * co)
|
|||
|
||||
sh = pa->param[n]->data.sh;
|
||||
|
||||
if (sh->number > 1) {
|
||||
cmistake(caster, co->order, 325, MSG_MAGIC);
|
||||
continue;
|
||||
}
|
||||
if (is_cursed(sh->attribs, &ct_flyingship)) {
|
||||
ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order,
|
||||
"error_spell_on_flying_ship", "ship", sh))
|
||||
|
|
|
@ -129,6 +129,19 @@ const char *locale_getstring(const locale * lang, const char *key)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const char *locale_plural(const struct locale *lang, const char *key, int n, bool warn) {
|
||||
assert(lang);
|
||||
assert(key);
|
||||
|
||||
if (n != 1) {
|
||||
char plural[32];
|
||||
snprintf(plural, 32, "%s_p", key);
|
||||
plural[31] = '\0';
|
||||
return locale_string(lang, plural, warn);
|
||||
}
|
||||
return locale_string(lang, key, warn);
|
||||
}
|
||||
|
||||
const char *locale_string(const locale * lang, const char *key, bool warn)
|
||||
{
|
||||
assert(lang);
|
||||
|
|
|
@ -32,6 +32,7 @@ extern "C" {
|
|||
const char *locale_getstring(const struct locale *lang,
|
||||
const char *key);
|
||||
const char *locale_string(const struct locale *lang, const char *key, bool warn); /* does fallback */
|
||||
const char *locale_plural(const struct locale *lang, const char *key, int n, bool warn);
|
||||
unsigned int locale_index(const struct locale *lang);
|
||||
const char *locale_name(const struct locale *lang);
|
||||
|
||||
|
|
Loading…
Reference in New Issue