* 3.2 (but the script can be run on older versions)
Level needed -
* Ruleset: Beginner
* Scipt LUA: None
After seeing this new ability in civ7, I thought, what a great idea for our explorer, so why not?
The new actions are:
1) Build Watchtower
2) Convert Unit (River) (the game's default "Convert Unit" action)
3) Convert Unit (Land or Sea) ("User Action 1" action)
Unlike the game's default action, the "User Action 1" restores all of the unit's hit points!
I believe that some units, like the Explorer, don't unbalance the game if they keep jumping around in the sea recovering every time they get hurt!
But of course, that's up to you!
At the end of this post I provide 3 rulesets with the new explorer configured for you to test.
So let's begin!
1) Actions.ruleset file
Copy and paste the following code into the actions.ruleset file, in the [actions] sector.
Code: Select all
ui_name_convert_unit = _("%sConvert Unit (River)%s")
ui_name_user_action_1 = _("%sConvert Unit (Land or Sea)%s")
user_action_1_target_kind = "Tile"
user_action_1_min_range = 0
user_action_1_max_range = 1
user_action_1_actor_consuming_always = FALSE
ui_name_user_action_2 = _("Build Watch%stower (1 turn without movement)%s")
user_action_2_target_kind = "Tile"
user_action_2_min_range = 0
user_action_2_max_range = 0
user_action_2_actor_consuming_always = FALSE
Code: Select all
; ----------------------------------------------------------------------------------------------------
; CONVERT UNIT
; ----------------------------------------------------------------------------------------------------
[actionenabler_convert_unit_anywhere]
action = "Convert Unit"
actor_reqs =
{ "type", "name", "range", "present"
; "Tech", "Seafaring", "Player", TRUE
"MinMoveFrags", "1", "Local", TRUE
"UnitState", "Transported", "Local", FALSE
"Extra", "Watchtower_READY", "Tile", FALSE
}
; ----------------------------------------------------------------------------------------------------
; USER ACTION 1 - Convert Unit
; ----------------------------------------------------------------------------------------------------
; Explorer
[actionenabler_user_action_convert_explorer]
action = "User Action 1"
actor_reqs =
{ "type", "name", "range", "present"
"UnitType", "Explorer", "Local", TRUE
"MinMoveFrags", "1", "Local", TRUE
"Extra", "Watchtower_READY", "Tile", FALSE
}
target_reqs =
{ "type", "name", "range", "present"
"TerrainClass", "Oceanic", "Tile", TRUE
"Extra", "River", "Tile", FALSE
}
; Raft
[actionenabler_user_action_convert_raft]
action = "User Action 1"
actor_reqs =
{ "type", "name", "range", "present"
"UnitType", "Raft", "Local", TRUE
"MinMoveFrags", "1", "Local", TRUE
}
target_reqs =
{ "type", "name", "range", "present"
"TerrainClass", "Land", "Tile", TRUE
"Extra", "Hut", "Tile", FALSE
"Extra", "River", "Tile", FALSE
}
; ----------------------------------------------------------------------------------------------------
; USER ACTION 2 - Watchtower
; ----------------------------------------------------------------------------------------------------
[actionenabler_user_action_2_explorer]
action = "User Action 2"
actor_reqs =
{ "type", "name", "range", "present"
"UnitType", "Explorer", "Local", TRUE
"MinMoveFrags", "1", "Local", TRUE
}
target_reqs =
{ "type", "name", "range", "present"
"TerrainClass", "Land", "Tile", TRUE
"Extra", "Watchtower_BEGIN", "Tile", FALSE
"Extra", "Watchtower_READY", "Tile", FALSE
}
2) Effects.ruleset file
Copy and paste the following code into the end of the effects.ruleset file.
Code: Select all
; ----------------------------------------------------------------------------------------------------
; USER ACTION EFFECTS - Build Watchtower
; ----------------------------------------------------------------------------------------------------
[effect_action_success_user_action_2]
type = "Action_Success_Actor_Move_Cost"
value = 65535
reqs =
{ "type", "name", "range", "quiet"
"Action", "User Action 2", "Local", TRUE
}
[effect_vision_watchtowers]
type = "Unit_Vision_Radius_Sq"
value = 25
reqs =
{ "type", "name", "range"
"Extra", "Watchtower_READY", "Tile"
"UnitType", "Explorer", "Local"
}
3) Terrain.ruleset file
Copy and paste the following code into the end of the terrain.ruleset file.
Code: Select all
; ----------------------------------------------------------------------------------------------------
; EXPLORER - WATCHTOWER
; ----------------------------------------------------------------------------------------------------
[extra_watchtower_begin]
name = _("Watchtower BEGIN")
rule_name = "Watchtower_BEGIN"
category = "Bonus"
graphic = "base.outpost"
graphic_alt = "extra.ruins"
activity_gfx = "None"
rmact_gfx = "None"
buildable = FALSE
helptext = ""
[extra_watchtower_ready]
name = _("Watchtower READY")
rule_name = "Watchtower_READY"
category = "Bonus"
graphic = "base.outpost"
graphic_alt = "extra.ruins"
activity_gfx = "None"
rmact_gfx = "None"
buildable = FALSE
helptext = ""
4) Units.ruleset file
This raft is a copy of the Trireme from the civ2civ3 ruleset with the ability to transport removed.
Adjust it to your ruleset.
Copy and paste the following code into the end of the units.ruleset file.
Code: Select all
; ----------------------------------------------------------------------------------------------------
; RAFT
; ----------------------------------------------------------------------------------------------------
[unit_raft]
name = _("Explorer Raft")
rule_name = "Raft"
convert_to = "Explorer"
class = "Trireme"
reqs =
{ "type", "name", "range"
"Tech", "Seafaring", "Player"
}
graphic = "u.feluca"
graphic_alt = "u.trireme"
graphic_alt2 = "u.trireme"
sound_move = "m_trireme"
sound_move_alt = "m_generic"
sound_fight = "f_trireme"
sound_fight_alt = "f_generic"
build_cost = 30
pop_cost = 0
attack = 0
defense = 1
hitpoints = 10
firepower = 1
move_rate = 6
vision_radius_sq = 10
transport_cap = 0
fuel = 0
uk_happy = 0
uk_shield = 1
uk_food = 0
uk_gold = 1
tp_defense = "Alight"
flags = "BadCityDefender", "HasNoZOC", "Provoking", "NonMil"
roles = "Explorer", "ExplorerStartUnit"
helptext = _("\
The Raft can travel on rivers, but it may not enter deep ocean\
tiles. It cannot attack other ships, though it\
may still defend itself when attacked.\
")
Code: Select all
[unit_explorer]
name = _("Explorer")
...
convert_to = "Raft"
...
5) Last but not least, the script.lua file
Copy and paste the following code into the end of the script.lua file.
Code: Select all
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
function action_finished_unit_callback(action, result, actor, target)
if actor then
local nmAction = action:rule_name()
if nmAction == 'User Action 1' then
run_convert_unit(actor, target)
elseif nmAction == 'User Action 2' then
run_watchtower(actor, target)
end
end
return false
end
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
function run_watchtower(actor, target)
local has_begin = actor.tile:has_extra('Watchtower_BEGIN')
local has_ready = actor.tile:has_extra('Watchtower_READY')
if not has_begin and not has_ready then
actor.tile:create_extra('Watchtower_BEGIN')
notify_watchtower_begin(actor)
end
end
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
function has_unit_type_name(unit, utype_name)
return (unit.utype.id == find.unit_type(utype_name).id)
end
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
function run_convert_unit(actor, target)
local unit_new = nil
local moves_left = 0
if has_unit_type_name(actor, 'Explorer') then
unit_new = find.unit_type('Raft')
elseif has_unit_type_name(actor, 'Raft') then
unit_new = find.unit_type('Explorer')
end
if unit_new and unit_new:can_exist_at_tile(target) then
actor.owner:create_unit(target, unit_new, 0, actor:get_homecity(), moves_left)
actor:kill('disbanded', actor.owner)
end
end
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
function player_phase_begin_callback(player)
services_watchtowers(player)
end
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
function services_watchtowers(player)
for unit in player:units_iterate() do
local unit_type = unit.utype:rule_name()
if unit_type == 'Explorer' then
if unit.tile:has_extra('Watchtower_BEGIN') then
unit.tile:remove_extra('Watchtower_BEGIN')
unit.tile:create_extra('Watchtower_READY')
unit:movement_disallow()
notify_watchtower_ready(unit)
elseif unit.tile:has_extra('Watchtower_READY') then
unit.tile:remove_extra('Watchtower_READY')
unit:movement_allow()
notify_watchtower_done(unit)
end
end
end
end
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
function unit_loss_watchtowers(unit, player, reason)
local unit_type = unit.utype:rule_name()
if unit_type == 'Explorer' then
unit.tile:remove_extra('Watchtower_BEGIN')
unit.tile:remove_extra('Watchtower_READY')
end
end
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
function notify_watchtower_begin(actor)
notify.event(actor.owner, actor.tile, E.UNIT_BECAME_VET,
string.format('%s will build a watchtower at coordinates %s.',
actor.utype:name_translation(),
actor.tile:link_text()))
end
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
function notify_watchtower_ready(actor)
notify.event(actor.owner, actor.tile, E.UNIT_BECAME_VET,
string.format('%s is observing the %s area. 1 turn without movement.',
actor.utype:name_translation(),
actor.tile:link_text()))
end
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
function notify_watchtower_done(actor)
notify.event(actor.owner, actor.tile, E.UNIT_BECAME_VET,
string.format('%s has finished mapping the %s area. Movement is allowed.',
actor.utype:name_translation(),
actor.tile:link_text()))
end
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
function notify_conversion(actor, unit_new, target)
notify.event(actor.owner, target.tile, E.UNIT_BUILT,
string.format('Unit %s was converted to %s in %s.',
actor.utype:name_translation(),
unit_new:name_translation(),
target:link_text()) )
end
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
signal.connect('unit_lost', 'unit_loss_watchtowers')
signal.connect('player_phase_begin', 'player_phase_begin_callback')
signal.connect('action_finished_unit_extras', 'action_finished_unit_callback')
signal.connect('action_finished_unit_self', 'action_finished_unit_callback')
signal.connect('action_finished_unit_tile', 'action_finished_unit_callback')
signal.connect('action_finished_unit_unit', 'action_finished_unit_callback')
signal.connect('action_finished_unit_units', 'action_finished_unit_callback')
signal.connect('action_finished_unit_city', 'action_finished_unit_callback')
-- ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=