add World Conquest II to mainline
For mainline we will just call it "World Conquest" World Conquest II is a coop multiplayer campaign of 5 scenarios for 1,2 or 3 players. It features highly randomized maps for replayability. Also custom item and training systems. The majority of the campaign is implemented in lua for better preformance. It also contains a custom era to be used together woth the campaign, since the default era is quite unbalanced for this coop gamemode against the ai. It for example makes sure that every faction has a leader. This is one of the most popular MP addons on wesnoth 1.14, 1.12 and older.
58
data/campaigns/World_Conquest/MODDING.txt
Normal file
|
@ -0,0 +1,58 @@
|
|||
This file describes how to make your addon work well together with
|
||||
world conquest 2. In particular how to write an era that can be used together with world conquest ii.
|
||||
|
||||
|
||||
Making an era that works well together with world conquest ii, is quite
|
||||
easy: just add the [world_conquest_data] tag to your [multiplayer_side] tag just as
|
||||
the standard word conquest2 era does, important: your era may not have
|
||||
require_download=no for this to work. Furthermore if your era contains
|
||||
new unit types that are not mainline wesnoth, don't forget to put an additional
|
||||
[world_conquest_data] in [era] to describe which trails these unit types should get
|
||||
when they are selected as heroes (use this to compensate weaker unit types).
|
||||
|
||||
To make an era/modification that also changes the enemy army unit types,
|
||||
make sure to define the wc2_init_enemy event and use it to set the enemy_army
|
||||
variable that should contains the pool of 'armies' that the enemies are chosen from:
|
||||
```
|
||||
[event]
|
||||
name = "wc2_init_enemy"
|
||||
[filter_conditional]
|
||||
[variable]
|
||||
name="wc2_enemy_army.length"
|
||||
equals=0
|
||||
[/variable]
|
||||
[/filter_conditional]
|
||||
[set_variables]
|
||||
name = "wc2_enemy_army"
|
||||
[literal]
|
||||
[group]
|
||||
id = "enemyfaction_id"
|
||||
recruit= "Orcish Grunt,Orcish Archer,Wolf Rider,Orcish Assassin,Troll Whelp"
|
||||
[recall]
|
||||
level2 = "Orcish Ruler, Orcish Slayer,..."
|
||||
level2 = "Orcish Warlord, Troll Warrior,..."
|
||||
[/recall]
|
||||
[commander]
|
||||
level1 = "Orcish Leader, Orcish Grunt,..."
|
||||
level2 = "Orcish Ruler, Orcish Slayer,..."
|
||||
level2 = "Orcish Warlord, Troll Warrior,..."
|
||||
[/commander]
|
||||
[leader]
|
||||
level2 = "Troll"
|
||||
level3 = "Troll Warrior"
|
||||
recruit = "Orcish Grunt,Orcish Archer,Troll Whelp"
|
||||
[/leader]
|
||||
[leader]
|
||||
level2 = "Orcish Warrior"
|
||||
level3 = "Orcish Warlord"
|
||||
recruit = "Orcish Grunt,Orcish Archer,Wolf Rider,Orcish Assassin"
|
||||
[/leader]
|
||||
....
|
||||
[/group]
|
||||
[/literal]
|
||||
[/set_variables]
|
||||
[/event]
|
||||
```
|
||||
|
||||
|
||||
TODO: how to overwrite training and artifacts.
|
48
data/campaigns/World_Conquest/STRUCTURE.txt
Normal file
|
@ -0,0 +1,48 @@
|
|||
A description of this addon's code:
|
||||
|
||||
This addon makes a lot use of lua wherever possible, even [side] definitions
|
||||
were moved to lua by using scenario_generation=lua, that is why the [multiplayer]
|
||||
tags are nearly empty. One of the main advantage of this is that this addon
|
||||
doesn't increase the wesnoth parsing time, also i just found lua easier to
|
||||
read and much easier to debug since it gives better error messages, and doesn’t
|
||||
require reloading the cache after changes were made.
|
||||
|
||||
The directory is organized as follows:
|
||||
|
||||
./lua/map :
|
||||
the files in ./lua/map contain the code that generate the content of the
|
||||
[multiplayer] tag, in particular [side] definitions, [event]s, map_data and
|
||||
[load_resource]. The biggest part of the scenario is the map generation,
|
||||
World conquest map generation works as follows: First we run the wesnoth
|
||||
default map generator (here: the files in lua/map/generator), then we run
|
||||
a custom lua scrips to fix it up (lua/map/postgeneration). For each
|
||||
scenario there ia a fixed set of generator+postgenerator pairs defined in
|
||||
lua/map/scenarios for each scenario.
|
||||
|
||||
./lua/shared_utils :
|
||||
libraries and helper functions that are used by both the map editor and
|
||||
during the actual game.
|
||||
|
||||
./lua/optional_mechanics :
|
||||
A few lua mechanics that works independent on the rest of the world conquest
|
||||
II code.
|
||||
|
||||
./lua/era :
|
||||
the code for the World Conquest era, this is in particular the recruitment in pair
|
||||
function. And delivering wc data that depends on the current era (for
|
||||
example which heroes should be available for which faction)
|
||||
|
||||
./lua/game_mechanics :
|
||||
The lua code that implements the custom game mechanics of World Conquest, that is:
|
||||
The dropping system, the invest system, the training system, World Conquest
|
||||
specific abilities, the bonus points system
|
||||
|
||||
./lua/campaign :
|
||||
The code specific to the wc2 campaign: the difficulties, victory conditions,
|
||||
enemy spawns etc.
|
||||
|
||||
./utils/gameplay :
|
||||
The training and artifact definitions
|
||||
|
||||
./utils/era :
|
||||
The factions of the World Conquest era.
|
14
data/campaigns/World_Conquest/TODO.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
* Balance, readd dunefolk.
|
||||
|
||||
* translatable strings are still a mess, some are defined at top of the file while other are defined in the middle.
|
||||
|
||||
* the artifacts file should be change in the same way as the training file wrt translatable strings.
|
||||
|
||||
* We should consider moving the pickup event implementation to core (and rename it)
|
||||
|
||||
* Maybe change the recruit costs for certain types of units. e.g. Fencers are too expensive, Dwarvish fighters are too cheap etc.
|
||||
|
||||
* Maybe readd the ruined Fence terrain but in better quality.
|
||||
|
||||
* The mapgeneratot used a deprecated mushroom terrain.
|
25
data/campaigns/World_Conquest/_main.cfg
Normal file
|
@ -0,0 +1,25 @@
|
|||
## MP Campaign (Scenarios in Multiplayer >> Random Maps)
|
||||
|
||||
#textdomain wesnoth-World_Conquest
|
||||
|
||||
{./config.cfg}
|
||||
|
||||
[textdomain]
|
||||
name="wesnoth-World_Conquest"
|
||||
[/textdomain]
|
||||
|
||||
#ifdef LOAD_WC2
|
||||
|
||||
[binary_path]
|
||||
path=data/campaigns/World_Conquest
|
||||
[/binary_path]
|
||||
|
||||
{./era}
|
||||
{./resources}
|
||||
{./scenarios}
|
||||
|
||||
{WORLD_CONQUEST_II_ERA}
|
||||
{WORLD_CONQUEST_II_ERA_RESOURCE}
|
||||
|
||||
{WORLD_CONQUEST_II_CAMPAIGN_RESOURCE}
|
||||
#endif
|
488
data/campaigns/World_Conquest/changelog.txt
Normal file
|
@ -0,0 +1,488 @@
|
|||
# Modification from World Conquest 1.10.10 (created by TL, maintained by Natasiel).
|
||||
|
||||
# Code, idea and design: tekelili
|
||||
Minor code contributors: ezysquire (forcefield), tsr (preset advancement)
|
||||
|
||||
# Playtesting: Bear, Honor, jb, paso, tekelili
|
||||
|
||||
# Text: TL, Natasiel, Rigor, tekelili
|
||||
|
||||
# Images: All custom images based in other authors files, but it is hard find out their names, sorry :(
|
||||
Several images created by doofus-01
|
||||
All editing work to adapt custom images and create new from mainline (poorly executed): tekelili
|
||||
|
||||
# PBL file
|
||||
title="World Conquest II"
|
||||
type="campaign_mp"
|
||||
icon= "misc/blank-hex.png~BG(140,85,75)~O(1%)~BLIT(units/elves-wood/sorceress.png~RC(magenta>green)~CROP(14,1,58,71))~BLIT(units/undead-necromancers/dark-sorcerer+female.png~RC(magenta>blue)~CROP(0,0,60,67),12,5)"
|
||||
author="tekelili, TL"
|
||||
description="Highly randomized and replayable, combat focused campaign for 1-3 players. Players and enemies can improve their armies with magic items, heroes and trainings. Includes an era with 10 factions.
|
||||
Campaign complete (Beta version).
|
||||
Scenarios can be found in Multiplayer >> Random Maps. More detailed info at website.
|
||||
(Expert level, 5 scenarios.)"
|
||||
[feedback]
|
||||
topic_id=39651
|
||||
[/feedback]
|
||||
passphrase=#####
|
||||
version=#####
|
||||
email=#####
|
||||
|
||||
|
||||
# Changelog:
|
||||
|
||||
0.8.2:
|
||||
- misc bugfixes, mostly related to the new lua map generator
|
||||
- Disable dune piercer and The empire faction, since units were
|
||||
removed from mainline
|
||||
|
||||
0.8:
|
||||
- A lot of code refactors.
|
||||
- port the whole postgenerator mapgen code to a scenario_generation=lua .
|
||||
- huge performance boost in the mapgen code.
|
||||
- the mapgenerators can now be used in the editor.
|
||||
- the start-of-scenario savefiles no don't determine anymore which
|
||||
typegenerator is chosen.
|
||||
- remove a lot of other code to lua. The only [event] remaining is from
|
||||
the custom_terrain_mod.
|
||||
- Pickuppable items no always show on top of decorative items.
|
||||
- Add a libary wc2_convert which is a schema bases wml <-> lua converter.
|
||||
- fix wc2_optional_attack effect in case that no attack machted the filter.
|
||||
- Adapt to mainline dunefolk name changes.
|
||||
|
||||
0.7.10.3
|
||||
- Fix village colors.
|
||||
- Fix error in mapgen code.
|
||||
|
||||
0.7.10
|
||||
- Improve mapgeneration speed.
|
||||
- Fix error when using alienera.
|
||||
|
||||
0.7.9.1
|
||||
- Fix enemy training.
|
||||
|
||||
0.7.9
|
||||
- The pickup promt can now be disabled in the wocopedia->settings page.
|
||||
- Fix unit not advancing after picking up an item that decrease max xp.
|
||||
- Improved gold carryover code to be compatiable with more mod addons.
|
||||
- Fixed unit images in messages not scaled in plot sequences.
|
||||
- Clear shroud after finding a hero in a bonus point.
|
||||
|
||||
0.7.8.2
|
||||
- Improve compatabiltiy with other add-ons and code cleanups.
|
||||
|
||||
0.7.8
|
||||
- Added confirmation promt when picking up items.
|
||||
- Fix ai side color when player changes colors.
|
||||
- Fix item drop message.
|
||||
- Fix bug in preset advancement
|
||||
|
||||
0.7.7
|
||||
- Fixed invest itemlist not increasing.
|
||||
|
||||
0.7.6
|
||||
- Fixed rare lua error when picking up training from bonus point if the
|
||||
player cannot pick up more training.
|
||||
|
||||
0.7.5
|
||||
- Fixed Gold pick in invest giving no gold.
|
||||
|
||||
0.7.4
|
||||
- Fixed 'Terror disguise' and 'Herald armor' not settings alignment.
|
||||
|
||||
0.7.3
|
||||
- Fixed wrong experience of recruited units and of units with epic trait.
|
||||
|
||||
0.7.2
|
||||
- Fixed show item info.
|
||||
- Added 'settings' section to wocopedia
|
||||
|
||||
0.7.1
|
||||
- Fixed shuffle starting locations
|
||||
|
||||
0.7
|
||||
- Alienera modification is no longer needed to play with other eras than wc2.
|
||||
- Most code moved to lua
|
||||
- New WoCopedia ui
|
||||
- New Invest ui
|
||||
- Observer can no no longer see the enemies side
|
||||
- unit can no longer pickup items that won't give them anything
|
||||
- fixed wesnoth 1.14 depercation wanrings
|
||||
- fixed wrong xp for units with epic trait
|
||||
- Improved advancement pick code so that it no longer needs to intercept recruit etc events.
|
||||
- reduced savefile size
|
||||
- use new scaling algorithm for missing portaits
|
||||
- compatabiltiy issue: when loading saves from older wc2 versions the invest artifact list will be regenerated.
|
||||
|
||||
0.6.13
|
||||
- Fixed crash when loading games caused by 'adamant armour '
|
||||
- Fixed Winter's bloom not giving cold resistance
|
||||
|
||||
0.6.12
|
||||
- added lua implementation of the default mapgens
|
||||
- fixed skeleton archer image not showing
|
||||
- Alien eras can now be enaled without changing core files.
|
||||
- Simpler implementation custom recall cost
|
||||
- Simpler implementation of additional advancement
|
||||
- Fixed upkeep of units with items
|
||||
- Fixed 'Adamot aromor' effect
|
||||
|
||||
0.6.11
|
||||
- synced=no for menu items
|
||||
- unitmarker and pya are now optional
|
||||
- misc refactors
|
||||
|
||||
0.6.10
|
||||
- bugfix
|
||||
|
||||
0.6.9
|
||||
- Adapt to wesnoth 1.14
|
||||
- Correct recruits show in faction select dialog
|
||||
|
||||
0.6.8
|
||||
- Redefined Trust pairs (intended as little nerf)
|
||||
- Added Chocobone to enemy recalls
|
||||
- Removed Young Ogre from pickable from lists without orcs
|
||||
- Removed as pickables leaders mages not available as random for Militia and Gang
|
||||
- Tweaked Dark, Melee, Ranger and Experience trainings
|
||||
- Now enemy undead units get benefict from item Melange (they consumed it while alive)
|
||||
- Tweaked how scale enemy recalls at scenarios 4,5 with enemy_power (now is more difficult for players at easier levels)
|
||||
- Scaled enemy commander xp bonus with unit level
|
||||
- Redefined roads and rivers near castles in Maritime generator
|
||||
- Fixed calling Alien Eras modification with wrong id
|
||||
- Fixed not fog update for hero found
|
||||
- Added explanation of carryover to WoCopedia. Improved bonus points names generation
|
||||
- Fixed custom feeding description not matching mainline one. Fixed drains special could be displayed twice on a unit.
|
||||
- "Terrific disguise" becomes "Terror disguise", "Winged Staff" becomes "Winged scepter"
|
||||
- Fixed version warnings not aimed to host.
|
||||
|
||||
0.6.7
|
||||
- Removed Mages as random leaders for Militia
|
||||
- Small buffs to enemy at scenario4: 1 commander upgraded to level2 and +1 supply village
|
||||
- Small buffs to enemy at last scenario: 2 commander upgraded to level3 and +2 supply villages
|
||||
- Supply village for enemy gives leader trait "expert" (it doesnt give +70 gold, just normal income and upkeep)
|
||||
- Small nerf to enemy recalls at 1p-2p modes to absorb buffs on comanders aimed for 3p
|
||||
- Added xp scenario based bonus to hero found
|
||||
- Scaled early finish gold bonus (before percentage) with number of players
|
||||
- Removed resistence bonus from item Ring of Power and added disengage weapon special
|
||||
- Removed secondary effect for flying units from item Winged Staff
|
||||
- Tweaked all trainings
|
||||
- Scaled army discipline bonus chance with scenario
|
||||
- Thug hero gets "resilent" as extra trait instead "fearless" and Young Ogre "epic" instead "expert"
|
||||
- Scaled enemy items at last map with difficulty
|
||||
- Simplified/tweaked several junky map generation rutines
|
||||
- Tweaked faction images
|
||||
- Fixed bug: heals +8 training not working over heals +4 units
|
||||
- Fixed some translation notes shown and lacking commander overlay for observers
|
||||
- Disabled ruiened wood birdge destruction for lacking good image and transition
|
||||
- Shorted scenario name to ease savefiles management
|
||||
|
||||
0.6.6
|
||||
- Redefined the Guild: Now can spam Dark Adept and Ghoul becomes paired with Elvish Shaman
|
||||
- Added as leaders: Troll Hero and Lieutenant for The Hand, Troll Hero for The Gang and The Horde
|
||||
- Tweaked Ranger, Movement and Experience Trainings
|
||||
- Added Troll Hero and Great Troll to enemy orc recalls. Added Troll Hero to comanders
|
||||
- Changed The Horde faction image
|
||||
- Fixed bug: full movement on recruit was giving 1 MP less when assigned on recruit before +22% moves
|
||||
|
||||
0.6.5.1
|
||||
- Added as leaders: Orcish Ruler for The Gang and The Horde, Elvish Lord for The Guild
|
||||
- Rescaled bonus gold and enemies trained with difficulty level
|
||||
- Fixed bug: possible OOS in carryover using non-integer values inside [gold]
|
||||
- Fixed bug: possible castle expanding recruit in map3 Savannah
|
||||
- Fixed bug: 2 filters chosing some wrong bonus-point-images on a few maps
|
||||
- Fixed bug: yard generated at 0,0 sometimes at map2 Paradise
|
||||
|
||||
0.6.5
|
||||
(Not compatible with previous versions)
|
||||
- Developed new alternative map4 (Wild)
|
||||
- Swaped Arif and khaiyal as desesters for Guild and Hand. Swaped Hakim and Jundi as desesters for Gang and Militia. Added Dwarvish Scout to Knalgans pickables heroes
|
||||
- Tewaked trainings beneficts. Changes training order to extend +10% health profit to all redudancy consolation +1HP bonus
|
||||
- Enemy pets get trait "expert". Some tweaks/fixes to enemy recall lists
|
||||
- Legendary Goblin Pillager gets leadership (to be consistent with Rouser path)
|
||||
- Harcoded suffle players starting position, to fix [generator] pattern
|
||||
- Fixed bug: impassible terrain could become invest item impossible to pick
|
||||
- Fixed bug: enemy castle expansion on map1 called after map repaint could expand recruit. Several minor changes to some generations
|
||||
- Fixed glitch: optional charge duplicating attacks after unit AMLA
|
||||
- Fixed typo: gold amount not displayed in expensive recall warning message
|
||||
- Changed item "Winter Bloom" resistance bonus to "up to 20" (it was "+50"), removed movement and defense bonus.
|
||||
- The Key now gives teleport animation
|
||||
- Improved decorative destruction (fences, rotten bridges)
|
||||
- Several code fixes to alievate save files size (still a lot to do in BfW 1.14)
|
||||
- Used image for invest training from mainline and removed custom one, as is the same from BfW 1.12.4
|
||||
- Disabled [allow_undo] in 2p/3p modes due to OOS in bfW 1.12
|
||||
- fixed [insert_tag] creating empty [if] to avoid bug in BfW 1.13
|
||||
|
||||
0.6.4.4
|
||||
- Fixed bug in generating starting positions for alien eras in 2p-1p modes due to key terrain_liked=
|
||||
|
||||
0.6.4.3
|
||||
- Developed new alternative final map (Feudal)
|
||||
- Increased forest amount on map3 Delta wich becomed too low after generation redesign
|
||||
|
||||
0.6.4.2
|
||||
- "legendary" is renamed as "epic". Walking Corpse and Goblin Spearman heroes get new "legendary" trait (enables special advances to Chocobone and Goblin Pillager)
|
||||
- Enemy leaders get trait "heroic"
|
||||
- Fixed glitch: unit taking only 1 item when 2 items placed on same map spot
|
||||
- Fixed typo in BfW version warning
|
||||
- WC II version becomes a variable to be consistent with code stored in savegame
|
||||
|
||||
0.6.4.1
|
||||
- Fixed bug:Northerens bonus heroes was added twice and loyalist none to point list (responsable of 2 goblins heroes on bonus list)
|
||||
- Redefined data structure relationship between campaign and era (ease adapt other eras)
|
||||
- Removed unneccesary hack for recall store due to behavior changed in BfW 1.12
|
||||
- Rewritten/redefined junky generator-postgeneration for map3 Delta
|
||||
- Tweaked map3 Wetland postgeneration with extra obstacles in zones lacking them
|
||||
- Eliminated all players amount reference in postgenerations and made them consistent with any map size. Eliminated chance of generation expanding recruit for all maps.
|
||||
- Fixed bug: enemy with feeding item not getting scenario-based hp buff (made it also scale with enemy power)
|
||||
- Improved chances of melee recalls for enemy Elf
|
||||
- Added version warning urging to upgrade to 1.12.2 or later
|
||||
|
||||
0.6.4
|
||||
- Redefined The Scourge: Ghost paired with Skirmisher and Guilder-Bat (trades better scouting for less use of specialists)
|
||||
- Redefined The Guild: Can spam Elf Fighter and Ghoul. Reduced random leaders to shamans, mages, dark adepts, and necrophages
|
||||
- Removed White Mage as random leader for The Gang (intended as neutral/flavor change; too many chances of white mages and few of orc leaders among other factions)
|
||||
- Army discipline bonus nerfed to 3%
|
||||
- small tweak to Ranger Tactics training
|
||||
- Fixed bug: recruit list not consistent for different eras after scenario transition
|
||||
- Small tweaks to generators Wicked adn Provinces
|
||||
- Fixed custom forest terrain code (small "bugs" with no gameplay effect)
|
||||
- Improved themed enemy: added outlaw to maps Wetland and Wicked
|
||||
- Added saurians and outlaws to enemy commander types
|
||||
- Each enemy faction will not get commanders of repeated faction along campaign
|
||||
- Added 2 new alternative supply village images, added 3 bonus point images
|
||||
- Improved pickup bonus point image syncro. Revised and added bonus names.
|
||||
- Fixed Classic WC junky code of store empty points as (1,1). Rewroten some code for ease reading
|
||||
- Added debug config option to end scenario
|
||||
|
||||
0.6.3.3
|
||||
- Developed new alternative map4 (Wicked)
|
||||
- Enemy xp bonus (to commanders and units with item) now scales with enemy_power
|
||||
- Fixed wrong number of iterations (swaped numbers) in scenario4 for 1p and 2p modes.
|
||||
|
||||
0.6.3.2
|
||||
- Fixed bug introduced in 0.6.3.1 giving error to players joining a new game (wrong key use inside [scenario] was cause)
|
||||
- Added old tropical forests to custom terrain (to enhance some maps decoration)
|
||||
- Changed bonus labels font to Lucida Sans Unicode for ease reading (I couldnt read well "l","i","n","r" with default font. I accept better ideas...)
|
||||
- Some postgeneration code optimized (roads iteration)
|
||||
|
||||
0.6.3.1
|
||||
- Developed new alternative map3 (Wetland)
|
||||
|
||||
0.6.3
|
||||
- Developed new alternative map3 (Coral)
|
||||
- Small adjust to experiency penalty scaling with difficulty
|
||||
- Forbidden enemy castle expansion on water and villages
|
||||
- Simplified plot at fork 3 and now correctly shows all enemy leaders in scenario 4 (plot text is provisional anyway)
|
||||
- Redefined some postgeneration rutines as events
|
||||
- Reduced resources consumed loading scenario events from variables
|
||||
- [modification] loads now events in every scenario, removed reload them
|
||||
|
||||
0.6.2.2
|
||||
- Fixed bug in Training buff "full movement on turn recruited or recalled".
|
||||
|
||||
0.6.2.1
|
||||
- The Horde can now spam Skirmisher and Naga
|
||||
|
||||
0.6.2
|
||||
- Buffed The Gang (now can spam Grunt, Assasin, Elvish Archer and Wose)
|
||||
- Small Buff to The Hand (now can spam Young Ogre and Heavy Infantryman)
|
||||
- Small Buff to Dark Training
|
||||
- Developed new alternative map2 (Clayey)
|
||||
- Chose Difficulty menu is fired now at start (instead at first recruit). This set experency penalty correctly for all units.
|
||||
- Changed Young Ogre for Khalifate hero as Deserter for 6 factions
|
||||
|
||||
0.6.1.7
|
||||
- Enemy nerfed at last map (-2 level3 recalls)
|
||||
- Decoration fix to map6 Industrial (roads)
|
||||
- Fixed training names in WoCopedia showed all as Melee
|
||||
|
||||
0.6.1.6
|
||||
- Developed new alternative final map (Industrial)
|
||||
- Fixed support for change side color not working well for less than 3 players
|
||||
- Map4 Podzol tweaked with some extra rough terrain
|
||||
|
||||
0.6.1.5
|
||||
- Fixed bug making players leaders not affected by experience penalty (introduced in 0.6.1)
|
||||
|
||||
0.6.1.4
|
||||
- Nerfed enemy at last map (-2 commanders)
|
||||
|
||||
0.6.1.3
|
||||
- Nerfed enemy at last map (-1 training and -2 level3 recalls)
|
||||
|
||||
0.6.1.2
|
||||
- Nerfed enemy at last map (-1 magic item and -1 training)
|
||||
- Fixed wrong "Dwarvish Ulfserker" as enemy recall instead "Dwarvish Berserker"
|
||||
- Code reorganization for enemy configuration.
|
||||
- Redefined as events some macros to alleviate disguised code bloat
|
||||
|
||||
0.6.1.1
|
||||
- Fixed typo making scenario 4 one enemy side become broken in some difficulties for 2 players
|
||||
- Enemy recalls at map 3 now scales with enemy power
|
||||
- The Cult can now spam Vampire Bat and Cavalryman
|
||||
- Duplicated orcs random leaders and removed Elder Wose for The Gang
|
||||
|
||||
0.6.1
|
||||
- Redefined The Guild: Ghoul is now paired with Elvish Fighter and Skeleton with Wose.
|
||||
- Duplicated Dark Sorcerer and Necrophage as random leaders for Guild and Cult. Removed Elder Wose for Guild.
|
||||
- Disabled The Empire as random faction (added config option to enable it)
|
||||
- Experiency penalty now scales with difficulty
|
||||
- Improved movement training lvl2. Move on recruit buff now allows also attack.
|
||||
|
||||
0.6.0.2
|
||||
- Changed Classic WC heores recall limit (was 6 maximun) to player castle size.
|
||||
- Ruffian hero gets legendary (was expert). Naffat hero gets resilient and Rami hero gets strong.
|
||||
- Fixed defense boost working bad for negative values due to different WML behavior in BfW 1.12
|
||||
- Fixed typo making castles 1 hex smaller in map3 Sulfurous
|
||||
- Small improves to melee and movement traings advanced levels
|
||||
|
||||
0.6.0.1
|
||||
- Developed new alternative final map (Maritime)
|
||||
|
||||
0.6
|
||||
- Buffed The Gang (now can spam Shaman and Orcish Archer)
|
||||
- Buffed trait "legendary"
|
||||
- Redefined WC II era events to make it copatible with other scenarios (integrated info recruit option)
|
||||
- Minor tweaks to map generation, menu appearence, and code organization
|
||||
- Fixed creation of useless variables in 2p and 1p modes
|
||||
|
||||
0.5.9.3.2
|
||||
- Improved Dark Training
|
||||
- Increased minimun keep separation in map2 Provinces and map4 Mines
|
||||
|
||||
0.5.9.3.1
|
||||
- Some map generation/decoration tweaks. Improved decorative destruction
|
||||
- Small improve to melee training
|
||||
|
||||
0.5.9.3
|
||||
- More changes to Empire. Test in progress
|
||||
|
||||
0.5.9.2
|
||||
- Buffed Cult (really hoping this is last one): Hakim paired with Walking corpose
|
||||
- Fixed alias for custom villages using add on terrain modification to new 1.11 code (they were giving only flat defense)
|
||||
|
||||
0.5.9.1
|
||||
- Developed new alternative map3 (Sulfurous)
|
||||
- Converted to road swamp castle conected to keep in map3 Jungle
|
||||
|
||||
0.5.9
|
||||
- Buffed The Cult (yea... again), now can spam more units
|
||||
- Some modifications/fixes in enemy comanders extra recruits lists
|
||||
|
||||
0.5.8.7.2
|
||||
- Removed Footpad from Empire recruit, now can spam Jundi
|
||||
|
||||
0.5.8.7.1
|
||||
- Guardsman changed for dwarvish fighter in empire recruit
|
||||
|
||||
0.5.8.7
|
||||
- redefined The Empire recruit. (First try to create faction was a mess)
|
||||
|
||||
0.5.8.6
|
||||
- fixed rerandomize recruit after map1 due to new [event] inside [era] behavior in BfW 1.11
|
||||
|
||||
0.5.8.5
|
||||
- empire buffed with 2 new pairs
|
||||
- Hakim heroe gets expert trait, jundi heroe gets strong trait
|
||||
|
||||
0.5.8.4
|
||||
- Replaced commander overlay for BfW 1.10 one
|
||||
- Buffed Empire
|
||||
|
||||
0.5.8.3
|
||||
- Developed new alternative map2 (Paradise)
|
||||
|
||||
0.5.8.2
|
||||
- Scaled unit images for missing portraits
|
||||
|
||||
0.5.8.1
|
||||
- Hakim hero gets "strong" trait
|
||||
- Replaced thief for thug in Empire deserters
|
||||
- Tweaked themed enemies adjacent villages
|
||||
- Some tweaks to map3 Delta and map4 Podzol generation
|
||||
|
||||
0.5.8
|
||||
- Added new faction with Khalifate units: The Empire
|
||||
- Added Khalifate heroes to bonus points
|
||||
- Fixed thread name in objectives
|
||||
|
||||
0.5.7.3
|
||||
- Developed new alternative map4 (Podzol)
|
||||
- Small fix to halo behavior
|
||||
- Small fixes to map decoration
|
||||
|
||||
0.5.7.2
|
||||
- Fixed buggy behavior in train benefict "optional charge"
|
||||
- Fixed wrong commanders and pickable heroes lists for The Guild
|
||||
|
||||
0.5.7.1
|
||||
- Redefined custom terrain config option as modification
|
||||
- Added allow_undo to all menu items but preset advacement
|
||||
- Fixed Classic WC bug: adamant armor not working as intended on some units after level
|
||||
- Small improve to Movement training maximun level
|
||||
- Reduced Discipline bonus for advanced trainers to 4%
|
||||
- Some code simplification and/or clarification
|
||||
|
||||
0.5.7
|
||||
- Redefined The Cult recruit to give a great buff to faction
|
||||
- Change in The Guild recruit intended as very small buff (also for flavor reasons).
|
||||
|
||||
0.5.6.0.1
|
||||
- Fixed bug in recall (making players need exced in 11 gold unit recall cost)
|
||||
|
||||
0.5.6
|
||||
- Developed new alternative map2 (Glaciers)
|
||||
- Developed new alternative map2 (Provinces)
|
||||
- Developed new alternative map4 (Mines)
|
||||
- Fixed minor bug in Classic WC jungle generator (mushroom max temperature)
|
||||
- Enemy allies recruits are now randomized instead pick first value of list
|
||||
- Forced lock scenario settings (but sides color for map1)
|
||||
|
||||
0.5.5.6.1
|
||||
- Fixed bug in random hero list creation for other eras (possible empty value)
|
||||
|
||||
0.5.5.6
|
||||
- Added config option to allow other eras (create random heroes lists)
|
||||
|
||||
0.5.5.5
|
||||
- Redifined The Cult pairs (intended as a very small buff)
|
||||
- Fixed bug causing not giving trainings in bonus points (introduced in 0.5.4)
|
||||
- Fixed undesired scroll to random unit in invest training
|
||||
- Fixed typo in trait "trained" description for ranger terrains specials
|
||||
- Added custom bonus images
|
||||
- Undead bosses get name
|
||||
- Removed clear map lables (generator bug solved in 1.11.1)
|
||||
|
||||
0.5.5
|
||||
- Added a new alternative map3: Delta
|
||||
- Fixed minor bug replacing a custom image in bonus
|
||||
- More acurated use of new 1.12 terrain forest. Minor decoration tweaks.
|
||||
- Redefined The Militia to slighty buff it. Target is (taking fighter/scout pair apart), give the best possible pairs. New image.
|
||||
- Removed Young Ogre from Heroes and Deserters of The Hand and added to its commanders.
|
||||
- Fixed low unintended finish gold bonus for 2p and 1p. (carry_over formula was not working well for less players)
|
||||
- Harcoded "village map amount" for finish gold bonus calculation. Fixes map generation as undesired source of stupid umbalance in players gold.
|
||||
- Split WoCopedia and recruit info (new images)
|
||||
|
||||
0.5.4.1
|
||||
- Fixed traings not giving correctly specials
|
||||
- Fixed typo in random leaders info
|
||||
|
||||
0.5.4 (developed for BfW v1.11 series)
|
||||
- Changed add on name to World Conquest II
|
||||
- Chanaged abilities descriptions to 1.12 format
|
||||
- Changed image file name to 1.12 path for thunderer,scout,skeleton,horseman,cavalryman(croped)
|
||||
- Added support for change side colors
|
||||
- Improved decoration using new 1.12 terrains
|
||||
- Removed unit name mark for special_overlay in recall list (1.12 includes overlays)
|
||||
- Redefined era code to make more easy additions and maintenance
|
||||
- Disabled era outside WC II and seted era as only one allowed for campaign (prevents crash)
|
||||
- Improved decorative destruction with custom terrain (snowed forests)
|
||||
- Improved Recruit info option (added units images)
|
||||
- Added deserters to WoCopedia factions. Improved WoCopedia design and readbility.
|
||||
- Developed a new help option to see again items info (rightclick on image)
|
||||
- Redefined The Hand pairs and random leaders to buff faction
|
||||
- Integrated translated version as config option
|
||||
- Increased trun limit in 2p and 1p versions. +25 gold each map for 1p.
|
||||
- Reduced enemy lvl2 recalls in map4 for lower difficulties.
|
||||
|
||||
(deleted changelog only valid for previous BfW versions)
|
34
data/campaigns/World_Conquest/config.cfg
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifdef EDITOR
|
||||
#ifndef LOAD_WC2
|
||||
#define LOAD_WC2
|
||||
#enddef
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MULTIPLAYER
|
||||
#ifndef LOAD_WC2
|
||||
#define LOAD_WC2
|
||||
#enddef
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LOAD_WC2
|
||||
|
||||
#ifdef IS_ADD_ON
|
||||
|
||||
#define ID_SUFFIX
|
||||
_umc#enddef
|
||||
|
||||
#define WC2_DIR
|
||||
~add-ons/World_Conquest_II/#enddef
|
||||
|
||||
#else
|
||||
|
||||
#define ID_SUFFIX
|
||||
#enddef
|
||||
|
||||
#define WC2_DIR
|
||||
campaigns/World_Conquest/#enddef
|
||||
|
||||
#endif
|
||||
#endif
|
316
data/campaigns/World_Conquest/era/campaign/heroes.cfg
Normal file
|
@ -0,0 +1,316 @@
|
|||
##############################################################
|
||||
|
||||
#define WORLD_CONQUEST_II_ERA_HEROES_TRAITS
|
||||
[trait_extra]
|
||||
types=Walking Corpse
|
||||
{WORLD_CONQUEST_II_TRAIT_LEGENDARY_ZOMBIE}
|
||||
[/trait_extra]
|
||||
[trait_extra]
|
||||
types=Goblin Spearman
|
||||
{WORLD_CONQUEST_II_TRAIT_LEGENDARY_GOBLIN}
|
||||
[/trait_extra]
|
||||
[trait_extra]
|
||||
types=Orcish Assassin,Young Ogre,Ruffian,Woodsman
|
||||
{WORLD_CONQUEST_II_TRAIT_EPIC}
|
||||
[/trait_extra]
|
||||
[trait_extra]
|
||||
types=Ghoul,Poacher,Thief,Footpad,Saurian Skirmisher,Vampire Bat,Peasant,Dune Herbalist
|
||||
{WORLD_CONQUEST_II_TRAIT_EXPERT}
|
||||
[/trait_extra]
|
||||
[trait_extra]
|
||||
types=Elvish Archer,Elvish Shaman,Elvish Scout,Elvish Fighter
|
||||
{TRAIT_DEXTROUS}
|
||||
[/trait_extra]
|
||||
[trait_extra]
|
||||
types=Dwarvish Guardsman,Dwarvish Ulfserker,Dwarvish Thunderer,Dwarvish Scout
|
||||
{TRAIT_HEALTHY}
|
||||
[/trait_extra]
|
||||
[trait_extra]
|
||||
types=Naga Fighter,Wolf Rider,Orcish Grunt,Drake Glider,Dune Rover,Dune Rider
|
||||
{TRAIT_STRONG}
|
||||
[/trait_extra]
|
||||
[trait_extra]
|
||||
types=Spearman,Fencer,Cavalryman,Merman Fighter,Merman Hunter,Mermaid Initiate,Dune Burner,Thug
|
||||
{TRAIT_RESILIENT}
|
||||
[/trait_extra]
|
||||
[trait_extra]
|
||||
types=Heavy Infantryman,Bowman,Skeleton,Skeleton Archer,Saurian Augur,Troll Whelp,Orcish Archer
|
||||
{TRAIT_FEARLESS}
|
||||
[/trait_extra]
|
||||
[hero_spawn_filter]
|
||||
types=Naga Fighter,Merman Fighter,Merman Hunter,Mermaid Initiate,
|
||||
[filter_location]
|
||||
[filter_radius]
|
||||
[not]
|
||||
terrain="M*,X*"
|
||||
[/not]
|
||||
[/filter_radius]
|
||||
terrain="W*,S*"
|
||||
radius=2
|
||||
[/filter_location]
|
||||
[/hero_spawn_filter]
|
||||
#enddef
|
||||
|
||||
#define WORLD_CONQUEST_II_TRAIT_HEROIC
|
||||
[trait]
|
||||
id=heroic
|
||||
male_name= {STR_HEROIC}
|
||||
female_name= {STR_HEROIC_FEMALE}
|
||||
[effect]
|
||||
apply_to=loyal
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=attack
|
||||
range=melee
|
||||
increase_damage=1
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=attack
|
||||
range=ranged
|
||||
increase_damage=1
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=hitpoints
|
||||
increase_total=5
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=hitpoints
|
||||
times=per level
|
||||
increase_total=1
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=movement
|
||||
increase=1
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=max_experience
|
||||
increase=-20%
|
||||
[/effect]
|
||||
[/trait]
|
||||
#enddef
|
||||
|
||||
#define WORLD_CONQUEST_II_TRAIT_EXPERT
|
||||
[trait]
|
||||
id=expert
|
||||
male_name= {STR_EXPERT}
|
||||
female_name= {STR_EXPERT_FEMALE}
|
||||
[effect]
|
||||
apply_to=attack
|
||||
range=melee
|
||||
increase_attacks=1
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=hitpoints
|
||||
increase_total=3
|
||||
[/effect]
|
||||
[/trait]
|
||||
#enddef
|
||||
|
||||
#define WORLD_CONQUEST_II_TRAIT_EPIC
|
||||
[trait]
|
||||
id=epic
|
||||
male_name= {STR_EPIC}
|
||||
female_name= {STR_EPIC_FEMALE}
|
||||
description= {STR_EPIC_DESCRIPTION}
|
||||
[effect]
|
||||
apply_to=hitpoints
|
||||
increase_total=6
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=attack
|
||||
increase_attacks=1
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=remove_advancement
|
||||
amlas=amla_default
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=max_experience
|
||||
lua_filter="wc2_utils.has_no_advances"
|
||||
|
||||
set=60
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=new_advancement
|
||||
lua_filter="wc2_utils.has_no_advances"
|
||||
|
||||
amlas=amla_default
|
||||
[advancement]
|
||||
strict_amla=yes
|
||||
max_times=100
|
||||
id=amla_default
|
||||
description= _ "Max HP bonus +6%"
|
||||
image="icons/amla-default.png"
|
||||
[effect]
|
||||
apply_to=hitpoints
|
||||
increase_total=6
|
||||
heal_full=yes
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=status
|
||||
remove=poisoned
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=status
|
||||
remove=slowed
|
||||
[/effect]
|
||||
[/advancement]
|
||||
[/effect]
|
||||
[/trait]
|
||||
#enddef
|
||||
|
||||
#define WORLD_CONQUEST_II_TRAIT_LEGENDARY_ZOMBIE
|
||||
[trait]
|
||||
id=legendary_zombie
|
||||
male_name= {STR_LEGENDARY}
|
||||
female_name= {STR_LEGENDARY_FEMALE}
|
||||
description= {STR_LEGENDARY_ZOMBIE_DESCRIPTION}
|
||||
[effect]
|
||||
apply_to=hitpoints
|
||||
increase_total=5
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=hitpoints
|
||||
times=per level
|
||||
increase_total=1
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=attack
|
||||
increase_attacks=1
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=attack
|
||||
type=pierce
|
||||
[set_specials]
|
||||
mode=append
|
||||
{WEAPON_SPECIAL_PLAGUE}
|
||||
[/set_specials]
|
||||
[/effect]
|
||||
[effect]
|
||||
[filter]
|
||||
type="Soulless"
|
||||
[/filter]
|
||||
apply_to=remove_advancement
|
||||
amlas=amla_default
|
||||
[/effect]
|
||||
[effect]
|
||||
[filter]
|
||||
type="Soulless"
|
||||
[/filter]
|
||||
apply_to=new_advancement
|
||||
types=Chocobone
|
||||
[/effect]
|
||||
[/trait]
|
||||
#enddef
|
||||
|
||||
#define WORLD_CONQUEST_II_TRAIT_LEGENDARY_GOBLIN
|
||||
[trait]
|
||||
id=legendary_goblin
|
||||
male_name= {STR_LEGENDARY}
|
||||
female_name= {STR_LEGENDARY_FEMALE}
|
||||
description= {STR_LEGENDARY_GOBLIN_DESCRIPTION}
|
||||
[effect]
|
||||
apply_to=hitpoints
|
||||
increase_total=5
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=hitpoints
|
||||
times=per level
|
||||
increase_total=1
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=attack
|
||||
increase_attacks=1
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=attack
|
||||
type=blade
|
||||
[set_specials]
|
||||
mode=append
|
||||
{WEAPON_SPECIAL_POISON}
|
||||
[/set_specials]
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=attack
|
||||
type=fire,blade
|
||||
increase_damage=1
|
||||
[/effect]
|
||||
{WCT_LEADERSHIP}
|
||||
[effect]
|
||||
[filter]
|
||||
level=1
|
||||
[/filter]
|
||||
apply_to=remove_advancement
|
||||
amlas=amla_default
|
||||
[/effect]
|
||||
[effect]
|
||||
[filter]
|
||||
level=1
|
||||
[/filter]
|
||||
apply_to=new_advancement
|
||||
types=Goblin Pillager
|
||||
[/effect]
|
||||
[/trait]
|
||||
#enddef
|
||||
|
||||
#textdomain wesnoth-multiplayer
|
||||
#define WORLD_CONQUEST_II_ERA_HEROES_TYPES
|
||||
[Northerners]
|
||||
name=_"Northerners"
|
||||
types="Orcish Grunt,Troll Whelp,Orcish Archer,Orcish Assassin,Orcish Leader"
|
||||
[/Northerners]
|
||||
[Northerners_All]
|
||||
types="Northerners,Naga Fighter"
|
||||
[/Northerners_All]
|
||||
[Rebels]
|
||||
name=_"Rebels"
|
||||
types="Mage,Elvish Fighter,Elvish Archer,Elvish Shaman,Elvish Scout,Wose"
|
||||
[/Rebels]
|
||||
[Rebels_All]
|
||||
types="Rebels,Merman Hunter,Mermaid Initiate"
|
||||
[/Rebels_All]
|
||||
[Loyalists]
|
||||
name=_"Loyalists"
|
||||
types="Cavalryman,Horseman,Spearman,Fencer,Heavy Infantryman,Bowman,Sergeant,Mage"
|
||||
[/Loyalists]
|
||||
[Loyalists_All]
|
||||
types="Loyalists,Merman Fighter"
|
||||
[/Loyalists_All]
|
||||
[Knalgans]
|
||||
name=_"Knalgan Alliance"
|
||||
types="Dwarvish Fighter,Thief,Dwarvish Thunderer,Poacher,Dwarvish Guardsman,Footpad,Dwarvish Ulfserker,Gryphon Rider"
|
||||
[/Knalgans]
|
||||
[Knalgans_All]
|
||||
types="Knalgans,Dwarvish Scout"
|
||||
[/Knalgans_All]
|
||||
[Drakes]
|
||||
name=_"Drakes"
|
||||
types="Drake Fighter,Drake Clasher,Drake Burner,Saurian Augur,Drake Glider,Saurian Skirmisher"
|
||||
[/Drakes]
|
||||
[Undead]
|
||||
name=_"Undead"
|
||||
types="Skeleton,Skeleton Archer,Ghoul,Dark Adept,Ghost"
|
||||
[/Undead]
|
||||
[Undead_All]
|
||||
types="Undead,Vampire Bat"
|
||||
[/Undead_All]
|
||||
[Bonus]
|
||||
types="Goblin Spearman,Walking Corpse,Ruffian,Peasant,Woodsman"
|
||||
[/Bonus]
|
||||
[Khalifate]
|
||||
#TODO: this contained 'Dune Piercer' in 1.14
|
||||
types="Dune Rover,Dune Rider,Dune Burner,Dune Herbalist,Dune Soldier"
|
||||
[/Khalifate]
|
||||
[Empire_commanders]
|
||||
types="Elvish Fighter,Dwarvish Fighter,Orcish Archer,Spearman,Drake Burner"
|
||||
[/Empire_commanders]
|
||||
[Empire_heroes]
|
||||
types="Mage,Bowman,Saurian Skirmisher,Drake Clasher,Elvish Archer,Wose,Gryphon Rider,Poacher,Orcish Leader,Wolf Rider,Ghost,Dark Adept"
|
||||
[/Empire_heroes]
|
||||
[Empire_deserters]
|
||||
types="Heavy Infantryman,Sergeant,Drake Glider,Saurian Augur,Elvish Shaman,Elvish Scout,Thug,Dwarvish Scout,Troll Whelp,Orcish Assassin,Ghoul,Skeleton Archer"
|
||||
[/Empire_deserters]
|
||||
[Bonus_All]
|
||||
types="Northerners_All,Rebels_All,Loyalists_All,Knalgans_All,Drakes,Undead_All,Young Ogre,Thug,Bonus,Khalifate"
|
||||
[/Bonus_All]
|
||||
#enddef
|
34
data/campaigns/World_Conquest/era/campaign/strings.cfg
Normal file
|
@ -0,0 +1,34 @@
|
|||
#textdomain wesnoth-World_Conquest
|
||||
|
||||
#define STR_HEROIC
|
||||
_ "heroic" #enddef
|
||||
|
||||
#define STR_HEROIC_FEMALE
|
||||
_ "female^heroic" #enddef
|
||||
|
||||
#define STR_EXPERT
|
||||
_ "expert" #enddef
|
||||
|
||||
#define STR_EXPERT_FEMALE
|
||||
_ "female^expert" #enddef
|
||||
|
||||
#define STR_EPIC
|
||||
_ "epic" #enddef
|
||||
|
||||
#define STR_EPIC_FEMALE
|
||||
_ "female^epic" #enddef
|
||||
|
||||
#define STR_EPIC_DESCRIPTION
|
||||
_ "Always AMLA with 60 XP and raises maximum health by 6 HP." #enddef
|
||||
|
||||
#define STR_LEGENDARY
|
||||
_ "legendary" #enddef
|
||||
|
||||
#define STR_LEGENDARY_FEMALE
|
||||
_ "female^legendary" #enddef
|
||||
|
||||
#define STR_LEGENDARY_ZOMBIE_DESCRIPTION
|
||||
_ "Special advancement to Chocobone enabled." #enddef
|
||||
|
||||
#define STR_LEGENDARY_GOBLIN_DESCRIPTION
|
||||
_ "Special advancement to Goblin Pillager enabled." #enddef
|
60
data/campaigns/World_Conquest/era/era.cfg
Normal file
|
@ -0,0 +1,60 @@
|
|||
## add subfolders
|
||||
{./factions}
|
||||
{./campaign}
|
||||
|
||||
#define WORLD_CONQUEST_II_ERA
|
||||
[era]
|
||||
id= "{STR_ERA_ID_WC_II}{ID_SUFFIX}"
|
||||
name= {STR_ERA_NAME_WC_II}{ID_SUFFIX}
|
||||
description= {STR_ERA_DESCRIPTION_WC_II}
|
||||
require_era=yes
|
||||
# addon_min_version="8.2"
|
||||
|
||||
{MULTIPLAYER_SIDE_RANDOM_WC_II}
|
||||
{MULTIPLAYER_SIDE_THE_TRUST}
|
||||
{MULTIPLAYER_SIDE_THE_GUILD}
|
||||
{MULTIPLAYER_SIDE_THE_HAND}
|
||||
{MULTIPLAYER_SIDE_THE_MILITIA}
|
||||
{MULTIPLAYER_SIDE_THE_HORDE}
|
||||
{MULTIPLAYER_SIDE_THE_CULT}
|
||||
{MULTIPLAYER_SIDE_THE_GANG}
|
||||
{MULTIPLAYER_SIDE_THE_SCOURGE}
|
||||
{MULTIPLAYER_SIDE_THE_ALLIANCE}
|
||||
#TODO: disabled since it contains 'Dune Piercer'
|
||||
# {MULTIPLAYER_SIDE_THE_EMPIRE}
|
||||
[load_resource]
|
||||
id = "wc2_era_res{ID_SUFFIX}"
|
||||
[/load_resource]
|
||||
[/era]
|
||||
#enddef
|
||||
|
||||
|
||||
#define WORLD_CONQUEST_II_ERA_RESOURCE
|
||||
## this is needed in both the era and the campaign, in particular in the campaign this data is used to generate the deserters and the ai sides.
|
||||
[resource]
|
||||
id = "wc2_era_res{ID_SUFFIX}"
|
||||
[lua]
|
||||
code = " wesnoth.dofile('{WC2_DIR}/lua/era_main.lua') "
|
||||
[/lua]
|
||||
[load_resource]
|
||||
id = "wc2_mainline_heroes{ID_SUFFIX}"
|
||||
[/load_resource]
|
||||
[/resource]
|
||||
|
||||
[resource]
|
||||
id = "wc2_mainline_heroes{ID_SUFFIX}"
|
||||
[world_conquest_data]
|
||||
[hero_types]
|
||||
{WORLD_CONQUEST_II_ERA_HEROES_TYPES}
|
||||
[/hero_types]
|
||||
## array of [trait_extra]
|
||||
{WORLD_CONQUEST_II_ERA_HEROES_TRAITS}
|
||||
[/world_conquest_data]
|
||||
[/resource]
|
||||
#enddef
|
||||
|
||||
#define WC_II_PAIR UNIT1 UNIT2
|
||||
[pair]
|
||||
types = {UNIT1} + "," + {UNIT2}
|
||||
[/pair]
|
||||
#enddef
|
12
data/campaigns/World_Conquest/era/factions/Random.cfg
Normal file
|
@ -0,0 +1,12 @@
|
|||
#textdomain wesnoth-multiplayer
|
||||
|
||||
#define MULTIPLAYER_SIDE_RANDOM_WC_II
|
||||
[multiplayer_side]
|
||||
id=Random
|
||||
name= _ "Random"
|
||||
image= units/random-dice.png
|
||||
random_faction=yes
|
||||
## The empire is not complteley blaanced to exclude it for now from random.
|
||||
except=The Empire
|
||||
[/multiplayer_side]
|
||||
#enddef
|
33
data/campaigns/World_Conquest/era/factions/The_Alliance.cfg
Normal file
|
@ -0,0 +1,33 @@
|
|||
#textdomain wesnoth-units
|
||||
|
||||
#define MULTIPLAYER_SIDE_THE_ALLIANCE
|
||||
[multiplayer_side]
|
||||
id=The Alliance
|
||||
name={STR_ALLIANCE}
|
||||
recruit=Spearman, Dwarvish Fighter,Bowman,Poacher,Horseman, Dwarvish Thunderer,Fencer,Thief,Mage,Dwarvish Ulfserker,Heavy Infantryman,Dwarvish Guardsman,Cavalryman,Footpad,Merman Fighter,Gryphon Rider
|
||||
image={IMG_ALLIANCE}
|
||||
type=random
|
||||
leader= Dwarvish Steelclad,Dwarvish Thunderguard,Dwarvish Stalwart,Rogue,Trapper,Lieutenant,Swordsman,Pikeman,Javelineer,Shock Trooper,Longbowman,White Mage,Red Mage
|
||||
random_leader= {RANDOM_LEADERS_ALLIANCE}
|
||||
[world_conquest_data]
|
||||
commanders=Loyalists,Knalgans
|
||||
heroes=Rebels_All,Drakes
|
||||
deserters=Undead,Northerners,Young Ogre
|
||||
deserters_names={STR_YOUNG_OGRE}+", "+{STR_THE_UNDEAD}+{STR_AND}+{STR_NORTHERENS}
|
||||
{WC_II_PAIR "Spearman" "Dwarvish Fighter"}
|
||||
{WC_II_PAIR "Bowman" "Poacher"}
|
||||
{WC_II_PAIR "Horseman" "Dwarvish Thunderer"}
|
||||
{WC_II_PAIR "Fencer" "Thief"}
|
||||
{WC_II_PAIR "Mage" "Dwarvish Ulfserker"}
|
||||
{WC_II_PAIR "Heavy Infantryman" "Dwarvish Guardsman"}
|
||||
{WC_II_PAIR "Cavalryman" "Footpad"}
|
||||
{WC_II_PAIR "Merman Fighter" "Gryphon Rider"}
|
||||
[/world_conquest_data]
|
||||
[/multiplayer_side]
|
||||
#enddef
|
||||
|
||||
#define RANDOM_LEADERS_ALLIANCE
|
||||
Dwarvish Steelclad,Dwarvish Thunderguard,Dwarvish Stalwart,Rogue,Trapper,Lieutenant,Swordsman,Pikeman,Longbowman,White Mage,Red Mage #enddef
|
||||
|
||||
#define IMG_ALLIANCE
|
||||
"misc/blank-hex.png~BLIT(units/dwarves/steelclad.png~RC(magenta>purple)~CROP(0,0,59,72),13,0)~BLIT(units/human-loyalists/lieutenant.png~RC(magenta>white)~CROP(16,0,56,72))" #enddef
|
39
data/campaigns/World_Conquest/era/factions/The_Cult.cfg
Normal file
|
@ -0,0 +1,39 @@
|
|||
#textdomain wesnoth-units
|
||||
|
||||
#define MULTIPLAYER_SIDE_THE_CULT
|
||||
[multiplayer_side]
|
||||
id=The Cult
|
||||
name={STR_CULT}
|
||||
recruit=Spearman,Spearman,Skeleton,Skeleton,Bowman,Bowman,Skeleton Archer,Skeleton Archer,Mage,Mage,Dark Adept,Dark Adept,Horseman,Horseman,Ghoul,Ghoul,Fencer,Fencer,Dune Herbalist,Walking Corpse,Heavy Infantryman,Ghost,Cavalryman,Cavalryman,Vampire Bat,Vampire Bat,Merman Fighter,Merman Fighter
|
||||
image={IMG_CULT}
|
||||
type=random
|
||||
leader= Lieutenant,Swordsman,Pikeman,Javelineer,Shock Trooper,Longbowman,White Mage,Red Mage,Dark Sorcerer,Revenant,Deathblade,Bone Shooter,Necrophage
|
||||
random_leader= {RANDOM_LEADERS_CULT}
|
||||
[world_conquest_data]
|
||||
commanders=Loyalists,Undead,Dune Herbalist
|
||||
heroes=Rebels_All,Knalgans_All
|
||||
deserters=Drakes,Northerners,Young Ogre
|
||||
deserters_names={STR_YOUNG_OGRE}+", "+{STR_DRAKES}+{STR_AND}+{STR_NORTHERENS}
|
||||
{WC_II_PAIR "Spearman" "Spearman"}
|
||||
{WC_II_PAIR "Skeleton" "Skeleton"}
|
||||
{WC_II_PAIR "Bowman" "Bowman"}
|
||||
{WC_II_PAIR "Skeleton Archer" "Skeleton Archer"}
|
||||
{WC_II_PAIR "Mage" "Mage"}
|
||||
{WC_II_PAIR "Dark Adept" "Dark Adept"}
|
||||
{WC_II_PAIR "Horseman" "Horseman"}
|
||||
{WC_II_PAIR "Ghoul" "Ghoul"}
|
||||
{WC_II_PAIR "Fencer" "Fencer"}
|
||||
{WC_II_PAIR "Dune Herbalist" "Walking Corpse"}
|
||||
{WC_II_PAIR "Heavy Infantryman" "Ghost"}
|
||||
{WC_II_PAIR "Cavalryman" "Cavalryman"}
|
||||
{WC_II_PAIR "Vampire Bat" "Vampire Bat"}
|
||||
{WC_II_PAIR "Merman Fighter" "Merman Fighter"}
|
||||
[/world_conquest_data]
|
||||
[/multiplayer_side]
|
||||
#enddef
|
||||
|
||||
#define RANDOM_LEADERS_CULT
|
||||
Lieutenant,Swordsman,Pikeman,Longbowman,White Mage,Red Mage,Dark Sorcerer,Dark Sorcerer,Revenant,Bone Shooter,Necrophage,Necrophage #enddef
|
||||
|
||||
#define IMG_CULT
|
||||
"misc/blank-hex.png~BLIT(units/human-loyalists/pikeman.png~RC(magenta>white)~CROP(0,3,58,69),14,0)~BLIT(units/undead-skeletal/revenant/revenant.png~RC(magenta>blue)~CROP(9,0,63,71),0,1)" #enddef
|
31
data/campaigns/World_Conquest/era/factions/The_Empire.cfg
Normal file
|
@ -0,0 +1,31 @@
|
|||
#textdomain wesnoth-units
|
||||
|
||||
#define MULTIPLAYER_SIDE_THE_EMPIRE
|
||||
[multiplayer_side]
|
||||
id=The Empire
|
||||
name={STR_EMPIRE}
|
||||
recruit=Dune Rover,Elvish Fighter,Dune Burner,Drake Burner,Dune Soldier,Spearman,Dune Piercer,Dwarvish Fighter,Dune Herbalist,Dune Herbalist,Dune Rider,Orcish Archer,Falcon,Vampire Bat
|
||||
image={IMG_EMPIRE}
|
||||
type=random
|
||||
leader= Dune Explorer,Dune Swordsman,Dune Spearguard,Dune Skirmisher,Dune Apothecary,Dune Scorcher
|
||||
random_leader= {RANDOM_LEADERS_EMPIRE}
|
||||
[world_conquest_data]
|
||||
commanders=Khalifate,Empire_commanders
|
||||
heroes=Empire_heroes
|
||||
deserters=Empire_deserters,Young Ogre
|
||||
{WC_II_PAIR "Dune Rover" "Elvish Fighter"}
|
||||
{WC_II_PAIR "Dune Burner" "Drake Burner"}
|
||||
{WC_II_PAIR "Dune Soldier" "Spearman"}
|
||||
{WC_II_PAIR "Dune Piercer" "Dwarvish Fighter"}
|
||||
{WC_II_PAIR "Dune Herbalist" "Dune Herbalist"}
|
||||
{WC_II_PAIR "Dune Rider" "Orcish Archer"}
|
||||
{WC_II_PAIR "Falcon" "Vampire Bat"}
|
||||
[/world_conquest_data]
|
||||
[/multiplayer_side]
|
||||
#enddef
|
||||
|
||||
#define RANDOM_LEADERS_EMPIRE
|
||||
Dune Explorer,Dune Swordsman,Dune Spearguard,Dune Skirmisher,Dune Scorcher #enddef
|
||||
|
||||
#define IMG_EMPIRE
|
||||
"misc/blank-hex.png~BLIT(units/dunefolk/scorcher.png~RC(magenta>teal)~CROP(0,13,57,59),15,0)~BLIT(units/dunefolk/explorer.png~RC(magenta>teal)~FL()~CROP(11,0,61,67),0,5)" #enddef
|
35
data/campaigns/World_Conquest/era/factions/The_Gang.cfg
Normal file
|
@ -0,0 +1,35 @@
|
|||
#textdomain wesnoth-units
|
||||
|
||||
#define MULTIPLAYER_SIDE_THE_GANG
|
||||
[multiplayer_side]
|
||||
id=The Gang
|
||||
name={STR_GANG}
|
||||
recruit=Troll Whelp,Elvish Fighter,Orcish Grunt,Orcish Grunt,Elvish Archer,Elvish Archer,Orcish Archer,Orcish Archer,Elvish Shaman,Elvish Shaman,Orcish Assassin,Orcish Assassin,Wose,Wose,Goblin Spearman,Mage,Wolf Rider,Elvish Scout,Naga Fighter,Merman Hunter
|
||||
image={IMG_GANG}
|
||||
type=random
|
||||
leader= Elvish Captain,Elvish Hero,Elvish Ranger,Elvish Marksman,Elvish Druid,Elvish Sorceress,Red Mage,Elder Wose,Orcish Ruler,Orcish Warrior,Troll Hero,Troll,Troll Rocklobber,Orcish Crossbowman,Orcish Slayer
|
||||
random_leader= {RANDOM_LEADERS_GANG}
|
||||
[world_conquest_data]
|
||||
commanders=Rebels,Northerners
|
||||
heroes=Drakes,Undead_All
|
||||
deserters=Loyalists,Knalgans,Dune Herbalist
|
||||
deserters_names={STR_HAKIM}+", "+{STR_LOYALISTS}+{STR_AND}+{STR_KNALGAN}
|
||||
{WC_II_PAIR "Troll Whelp" "Elvish Fighter"}
|
||||
{WC_II_PAIR "Orcish Grunt" "Orcish Grunt"}
|
||||
{WC_II_PAIR "Elvish Archer" "Elvish Archer"}
|
||||
{WC_II_PAIR "Orcish Archer" "Orcish Archer"}
|
||||
{WC_II_PAIR "Elvish Shaman" "Elvish Shaman"}
|
||||
{WC_II_PAIR "Orcish Assassin" "Orcish Assassin"}
|
||||
{WC_II_PAIR "Wose" "Wose"}
|
||||
{WC_II_PAIR "Goblin Spearman" "Mage"}
|
||||
{WC_II_PAIR "Wolf Rider" "Elvish Scout"}
|
||||
{WC_II_PAIR "Naga Fighter" "Merman Hunter"}
|
||||
[/world_conquest_data]
|
||||
[/multiplayer_side]
|
||||
#enddef
|
||||
|
||||
#define RANDOM_LEADERS_GANG
|
||||
Elvish Captain,Elvish Hero,Elvish Ranger,Elvish Marksman,Elvish Druid,Elvish Sorceress,Red Mage,Orcish Ruler,Troll Hero,Troll,Troll,Orcish Warrior,Orcish Warrior,Orcish Crossbowman,Orcish Crossbowman #enddef
|
||||
|
||||
#define IMG_GANG
|
||||
"misc/blank-hex.png~BLIT(units/orcs/xbowman.png~RC(magenta>red)~CROP(0,8,54,64),18,0)~BLIT(units/elves-wood/ranger.png~RC(magenta>green)~CROP(15,0,57,72),0,0)" #enddef
|
35
data/campaigns/World_Conquest/era/factions/The_Guild.cfg
Normal file
|
@ -0,0 +1,35 @@
|
|||
#textdomain wesnoth-units
|
||||
|
||||
#define MULTIPLAYER_SIDE_THE_GUILD
|
||||
[multiplayer_side]
|
||||
id=The Guild
|
||||
name={STR_GUILD}
|
||||
recruit=Elvish Fighter,Elvish Fighter,Dark Adept,Dark Adept,Elvish Archer,Skeleton Archer,Mage,Walking Corpse,Elvish Shaman,Ghoul,Wose,Skeleton,Elvish Scout,Vampire Bat,Ghost,Ghost,Merman Hunter,Merman Hunter,Mermaid Initiate,Mermaid Initiate
|
||||
image={IMG_GUILD}
|
||||
type=random
|
||||
leader=Elvish Lord,Elvish Captain,Elvish Hero,Elvish Ranger,Elvish Marksman,Elvish Druid,Elvish Sorceress,White Mage,Red Mage,Elder Wose,Dark Sorcerer,Revenant,Deathblade,Bone Shooter,Necrophage
|
||||
random_leader= {RANDOM_LEADERS_GUILD}
|
||||
[world_conquest_data]
|
||||
commanders=Rebels,Undead
|
||||
heroes=Knalgans_All,Northerners_All,Young Ogre
|
||||
deserters=Loyalists,Drakes,Dune Soldier
|
||||
deserters_names={STR_ARIF}+", "+{STR_LOYALISTS}+{STR_AND}+{STR_DRAKES}
|
||||
{WC_II_PAIR "Elvish Fighter" "Elvish Fighter"}
|
||||
{WC_II_PAIR "Dark Adept" "Dark Adept"}
|
||||
{WC_II_PAIR "Elvish Archer" "Skeleton Archer"}
|
||||
{WC_II_PAIR "Mage" "Walking Corpse"}
|
||||
{WC_II_PAIR "Elvish Shaman" "Ghoul"}
|
||||
{WC_II_PAIR "Wose" "Skeleton"}
|
||||
{WC_II_PAIR "Elvish Scout" "Vampire Bat"}
|
||||
{WC_II_PAIR "Ghost" "Ghost"}
|
||||
{WC_II_PAIR "Merman Hunter" "Merman Hunter"}
|
||||
{WC_II_PAIR "Mermaid Initiate" "Mermaid Initiate"}
|
||||
[/world_conquest_data]
|
||||
[/multiplayer_side]
|
||||
#enddef
|
||||
|
||||
#define RANDOM_LEADERS_GUILD
|
||||
Elvish Lord,Elvish Druid,Elvish Sorceress,White Mage,Red Mage,Dark Sorcerer,Dark Sorcerer,Necrophage,Necrophage #enddef
|
||||
|
||||
#define IMG_GUILD
|
||||
"misc/blank-hex.png~BLIT(units/elves-wood/sorceress.png~RC(magenta>green)~CROP(14,1,58,71))~BLIT(units/undead-necromancers/dark-sorcerer+female.png~RC(magenta>blue)~CROP(0,0,60,67),12,5)" #enddef
|
36
data/campaigns/World_Conquest/era/factions/The_Hand.cfg
Normal file
|
@ -0,0 +1,36 @@
|
|||
#textdomain wesnoth-units
|
||||
|
||||
#define MULTIPLAYER_SIDE_THE_HAND
|
||||
[multiplayer_side]
|
||||
id=The Hand
|
||||
name={STR_HAND}
|
||||
recruit=Spearman,Orcish Grunt,Bowman,Orcish Assassin,Mage,Orcish Archer,Troll Whelp,Troll Whelp,Heavy Infantryman,Heavy Infantryman,Young Ogre,Young Ogre,Cavalryman,Wolf Rider,Horseman,Orcish Leader,Fencer,Goblin Spearman,Merman Fighter,Naga Fighter
|
||||
image={IMG_HAND}
|
||||
type=random
|
||||
leader=Lieutenant,Swordsman,Pikeman,Javelineer,Shock Trooper,Longbowman,White Mage,Red Mage,Orcish Warrior,Troll,Troll Rocklobber,Orcish Crossbowman,Orcish Slayer,Orcish Ruler,Troll Hero
|
||||
random_leader= {RANDOM_LEADERS_HAND}
|
||||
[world_conquest_data]
|
||||
commanders=Loyalists,Northerners,Young Ogre
|
||||
heroes=Undead_All,Rebels_All
|
||||
# TODO: this contained 'Dune Piercer' in 1.14
|
||||
deserters=Knalgans,Drakes
|
||||
deserters_names={STR_KHAIYAL}+", "+{STR_KNALGAN}+{STR_AND}+{STR_DRAKES}
|
||||
{WC_II_PAIR "Spearman" "Orcish Grunt"}
|
||||
{WC_II_PAIR "Bowman" "Orcish Assassin"}
|
||||
{WC_II_PAIR "Mage" "Orcish Archer"}
|
||||
{WC_II_PAIR "Troll Whelp" "Troll Whelp"}
|
||||
{WC_II_PAIR "Heavy Infantryman" "Heavy Infantryman"}
|
||||
{WC_II_PAIR "Young Ogre" "Young Ogre"}
|
||||
{WC_II_PAIR "Cavalryman" "Wolf Rider"}
|
||||
{WC_II_PAIR "Horseman" "Orcish Leader"}
|
||||
{WC_II_PAIR "Fencer" "Goblin Spearman"}
|
||||
{WC_II_PAIR "Merman Fighter" "Naga Fighter"}
|
||||
[/world_conquest_data]
|
||||
[/multiplayer_side]
|
||||
#enddef
|
||||
|
||||
#define RANDOM_LEADERS_HAND
|
||||
White Mage,White Mage,Orcish Ruler,Orcish Ruler,Lieutenant,Troll Hero #enddef
|
||||
|
||||
#define IMG_HAND
|
||||
"misc/blank-hex.png~BLIT(units/human-magi/white-mage.png~RC(magenta>white)~CROP(18,0,54,72))~BLIT(units/orcs/ruler.png~RC(magenta>red)~CROP(0,0,58,72),14,0)" #enddef
|
33
data/campaigns/World_Conquest/era/factions/The_Horde.cfg
Normal file
|
@ -0,0 +1,33 @@
|
|||
#textdomain wesnoth-units
|
||||
|
||||
#define MULTIPLAYER_SIDE_THE_HORDE
|
||||
[multiplayer_side]
|
||||
id=The Horde
|
||||
name={STR_HORDE}
|
||||
recruit=Orcish Grunt,Drake Fighter,Orcish Archer,Drake Burner,Orcish Assassin,Saurian Augur,Troll Whelp,Drake Clasher,Wolf Rider,Drake Glider,Goblin Spearman,Goblin Spearman,Saurian Skirmisher,Saurian Skirmisher,Naga Fighter,Naga Fighter
|
||||
image={IMG_HORDE}
|
||||
type=random
|
||||
leader= Orcish Ruler,Orcish Warrior,Troll Hero,Troll,Troll Rocklobber,Orcish Crossbowman,Orcish Slayer,Drake Flare,Fire Drake,Drake Arbiter,Drake Thrasher,Drake Warrior,Saurian Oracle,Saurian Soothsayer
|
||||
random_leader= {RANDOM_LEADERS_HORDE}
|
||||
[world_conquest_data]
|
||||
commanders=Drakes,Northerners
|
||||
heroes=Undead_All,Loyalists_All
|
||||
deserters=Knalgans,Rebels,Dune Rider
|
||||
deserters_names={STR_RAMI}+", "+{STR_KNALGAN}+{STR_AND}+{STR_REBELS}
|
||||
{WC_II_PAIR "Orcish Grunt" "Drake Fighter"}
|
||||
{WC_II_PAIR "Orcish Archer" "Drake Burner"}
|
||||
{WC_II_PAIR "Orcish Assassin" "Saurian Augur"}
|
||||
{WC_II_PAIR "Troll Whelp" "Drake Clasher"}
|
||||
{WC_II_PAIR "Wolf Rider" "Drake Glider"}
|
||||
{WC_II_PAIR "Goblin Spearman" "Goblin Spearman"}
|
||||
{WC_II_PAIR "Saurian Skirmisher" "Saurian Skirmisher"}
|
||||
{WC_II_PAIR "Naga Fighter" "Naga Fighter"}
|
||||
[/world_conquest_data]
|
||||
[/multiplayer_side]
|
||||
#enddef
|
||||
|
||||
#define RANDOM_LEADERS_HORDE
|
||||
Orcish Ruler,Troll Hero,Orcish Warrior,Orcish Warrior,Troll,Troll,Orcish Crossbowman,Orcish Crossbowman,Drake Flare,Fire Drake,Fire Drake,Drake Arbiter,Drake Arbiter,Drake Thrasher,Drake Thrasher,Drake Warrior,Drake Warrior #enddef
|
||||
|
||||
#define IMG_HORDE
|
||||
"misc/blank-hex.png~BLIT(units/drakes/warrior.png~RC(magenta>orange)~CROP(0,7,66,65),6,0)~BLIT(units/orcs/warrior.png~RC(magenta>red)~CROP(17,0,55,65),0,7)" #enddef
|
33
data/campaigns/World_Conquest/era/factions/The_Militia.cfg
Normal file
|
@ -0,0 +1,33 @@
|
|||
#textdomain wesnoth-units
|
||||
|
||||
#define MULTIPLAYER_SIDE_THE_MILITIA
|
||||
[multiplayer_side]
|
||||
id=The Militia
|
||||
name={STR_MILITIA}
|
||||
recruit=Dwarvish Fighter,Elvish Scout,Thug,Elvish Fighter,Dwarvish Thunderer,Elvish Archer,Poacher,Elvish Shaman,Dwarvish Guardsman,Wose,Footpad,Mage,Dwarvish Ulfserker,Thief,Gryphon Rider,Merman Hunter
|
||||
image={IMG_MILITIA}
|
||||
type=random
|
||||
leader= Elvish Captain,Elvish Hero,Elvish Ranger,Elvish Marksman,Elvish Druid,Elvish Sorceress,Elder Wose,Dwarvish Steelclad,Dwarvish Thunderguard,Dwarvish Stalwart,Rogue,Trapper,Bandit
|
||||
random_leader= {RANDOM_LEADERS_MILITIA}
|
||||
[world_conquest_data]
|
||||
commanders=Rebels,Knalgans,Thug
|
||||
heroes=Northerners_All,Young Ogre,Drakes
|
||||
deserters=Undead,Loyalists,Dune Rover
|
||||
deserters_names={STR_JUNDI}+", "+{STR_THE_UNDEAD}+{STR_AND}+{STR_LOYALISTS}
|
||||
{WC_II_PAIR "Dwarvish Fighter" "Elvish Scout"}
|
||||
{WC_II_PAIR "Thug" "Elvish Fighter"}
|
||||
{WC_II_PAIR "Dwarvish Thunderer" "Elvish Archer"}
|
||||
{WC_II_PAIR "Poacher" "Elvish Shaman"}
|
||||
{WC_II_PAIR "Dwarvish Guardsman" "Wose"}
|
||||
{WC_II_PAIR "Footpad" "Mage"}
|
||||
{WC_II_PAIR "Dwarvish Ulfserker" "Thief"}
|
||||
{WC_II_PAIR "Gryphon Rider" "Merman Hunter"}
|
||||
[/world_conquest_data]
|
||||
[/multiplayer_side]
|
||||
#enddef
|
||||
|
||||
#define RANDOM_LEADERS_MILITIA
|
||||
Elvish Captain,Elvish Hero,Elvish Ranger,Elvish Marksman,Elvish Druid,Elvish Sorceress,Elder Wose,Dwarvish Steelclad,Dwarvish Thunderguard,Dwarvish Stalwart,Rogue,Trapper,Bandit #enddef
|
||||
|
||||
#define IMG_MILITIA
|
||||
"misc/blank-hex.png~BLIT(units/human-outlaws/bandit.png~RC(magenta>purple)~FL()~CROP(12,4,60,68))~BLIT(units/elves-wood/captain.png~RC(magenta>green)~CROP(0,0,57,72),15,0)" #enddef
|
32
data/campaigns/World_Conquest/era/factions/The_Scourge.cfg
Normal file
|
@ -0,0 +1,32 @@
|
|||
#textdomain wesnoth-units
|
||||
|
||||
#define MULTIPLAYER_SIDE_THE_SCOURGE
|
||||
[multiplayer_side]
|
||||
id=The Scourge
|
||||
name={STR_SCOURGE}
|
||||
recruit=Skeleton,Drake Fighter,Skeleton Archer,Drake Burner,Dark Adept,Saurian Augur,Ghoul,Drake Clasher,Ghost,Saurian Skirmisher,Vampire Bat,Drake Glider,Walking Corpse,Walking Corpse
|
||||
image={IMG_SCOURGE}
|
||||
type=random
|
||||
leader=Dark Sorcerer,Revenant,Deathblade,Bone Shooter,Necrophage,Drake Flare,Fire Drake,Drake Arbiter,Drake Thrasher,Drake Warrior,Saurian Oracle,Saurian Soothsayer
|
||||
random_leader= {RANDOM_LEADERS_SCOURGE}
|
||||
[world_conquest_data]
|
||||
commanders=Drakes,Undead
|
||||
heroes=Loyalists_All,Knalgans_All
|
||||
deserters=Rebels,Northerners,Young Ogre
|
||||
deserters_names={STR_YOUNG_OGRE}+", "+{STR_REBELS}+{STR_AND}+{STR_NORTHERENS}
|
||||
{WC_II_PAIR "Skeleton" "Drake Fighter"}
|
||||
{WC_II_PAIR "Skeleton Archer" "Drake Burner"}
|
||||
{WC_II_PAIR "Dark Adept" "Saurian Augur"}
|
||||
{WC_II_PAIR "Ghoul" "Drake Clasher"}
|
||||
{WC_II_PAIR "Ghost" "Saurian Skirmisher"}
|
||||
{WC_II_PAIR "Vampire Bat" "Drake Glider"}
|
||||
{WC_II_PAIR "Walking Corpse" "Walking Corpse"}
|
||||
[/world_conquest_data]
|
||||
[/multiplayer_side]
|
||||
#enddef
|
||||
|
||||
#define RANDOM_LEADERS_SCOURGE
|
||||
Dark Sorcerer,Revenant,Bone Shooter,Necrophage,Drake Flare,Fire Drake,Drake Arbiter,Drake Thrasher,Drake Warrior #enddef
|
||||
|
||||
#define IMG_SCOURGE
|
||||
"misc/blank-hex.png~BLIT(units/undead/necrophage.png~RC(magenta>blue)~CROP(0,13,55,59),17,0)~BLIT(units/drakes/flare.png~RC(magenta>orange)~CROP(10,0,62,67),0,5)" #enddef
|
32
data/campaigns/World_Conquest/era/factions/The_Trust.cfg
Normal file
|
@ -0,0 +1,32 @@
|
|||
#textdomain wesnoth-units
|
||||
|
||||
#define MULTIPLAYER_SIDE_THE_TRUST
|
||||
[multiplayer_side]
|
||||
id=The Trust
|
||||
name={STR_TRUST}
|
||||
recruit=Drake Fighter,Dwarvish Fighter,Drake Burner,Dwarvish Thunderer,Saurian Augur,Dwarvish Ulfserker,Drake Clasher,Dwarvish Guardsman,Saurian Skirmisher,Poacher,Drake Glider,Footpad,Thief,Thief
|
||||
image={IMG_TRUST}
|
||||
type=random
|
||||
leader= Dwarvish Steelclad,Dwarvish Thunderguard,Dwarvish Stalwart,Rogue,Trapper,Drake Flare,Fire Drake,Drake Arbiter,Drake Thrasher,Drake Warrior,Saurian Oracle,Saurian Soothsayer
|
||||
random_leader= {RANDOM_LEADERS_TRUST}
|
||||
[world_conquest_data]
|
||||
commanders=Drakes,Knalgans
|
||||
heroes=Loyalists_All,Northerners_All,Young Ogre
|
||||
deserters=Rebels,Undead,Dune Burner
|
||||
deserters_names={STR_NAFFAT}+", "+{STR_REBELS}+{STR_AND}+{STR_THE_UNDEAD}
|
||||
{WC_II_PAIR "Drake Fighter" "Dwarvish Fighter"}
|
||||
{WC_II_PAIR "Drake Burner" "Dwarvish Thunderer"}
|
||||
{WC_II_PAIR "Saurian Augur" "Dwarvish Ulfserker"}
|
||||
{WC_II_PAIR "Drake Clasher" "Dwarvish Guardsman"}
|
||||
{WC_II_PAIR "Saurian Skirmisher" "Poacher"}
|
||||
{WC_II_PAIR "Drake Glider" "Footpad"}
|
||||
{WC_II_PAIR "Thief" "Thief"}
|
||||
[/world_conquest_data]
|
||||
[/multiplayer_side]
|
||||
#enddef
|
||||
|
||||
#define RANDOM_LEADERS_TRUST
|
||||
Dwarvish Steelclad,Dwarvish Thunderguard,Dwarvish Stalwart,Rogue,Trapper,Drake Flare,Fire Drake,Drake Arbiter,Drake Thrasher,Drake Warrior #enddef
|
||||
|
||||
#define IMG_TRUST
|
||||
"misc/blank-hex.png~BLIT(units/dwarves/stalwart.png~RC(magenta>purple)~CROP(0,20,55,52),17,0)~BLIT(units/drakes/arbiter.png~RC(magenta>orange)~CROP(8,0,64,67),0,5)" #enddef
|
89
data/campaigns/World_Conquest/era/factions/strings.cfg
Normal file
|
@ -0,0 +1,89 @@
|
|||
#textdomain wesnoth-World_Conquest
|
||||
|
||||
#define STR_ERA_ID_WC_II
|
||||
world_conquest_era#enddef
|
||||
|
||||
#define STR_ERA_NAME_WC_II
|
||||
_"World Conquest" #enddef
|
||||
|
||||
#define STR_ERA_DESCRIPTION_WC_II
|
||||
_"Units are defined as pairs in recruit list: Every time a unit is recruited, it is remplaced by its pair. This era is designed to be balanced playing World Conquest II.
|
||||
Includes an in-game help to know pairs status, with a right-click on an emty hex." #enddef
|
||||
|
||||
#define STR_HORDE
|
||||
_"The Horde" #enddef
|
||||
|
||||
#define STR_ALLIANCE
|
||||
_"The Alliance" #enddef
|
||||
|
||||
#define STR_GUILD
|
||||
_"The Guild" #enddef
|
||||
|
||||
#define STR_TRUST
|
||||
_"The Trust" #enddef
|
||||
|
||||
#define STR_GANG
|
||||
_"The Gang" #enddef
|
||||
|
||||
#define STR_CULT
|
||||
_"The Cult" #enddef
|
||||
|
||||
#define STR_MILITIA
|
||||
_"The Militia" #enddef
|
||||
|
||||
#define STR_SCOURGE
|
||||
_"The Scourge" #enddef
|
||||
|
||||
#define STR_HAND
|
||||
_"The Hand" #enddef
|
||||
|
||||
#define STR_EMPIRE
|
||||
_"The Empire" #enddef
|
||||
|
||||
######################################
|
||||
#################################
|
||||
#textdomain wesnoth-units
|
||||
#################################
|
||||
|
||||
#define STR_ARIF
|
||||
_ "Dune Soldier" #enddef
|
||||
|
||||
#define STR_HAKIM
|
||||
_ "Dune Herbalist" #enddef
|
||||
|
||||
#define STR_JUNDI
|
||||
_ "Dune Rover" #enddef
|
||||
|
||||
#define STR_KHAIYAL
|
||||
_ "Dune Piercer" #enddef
|
||||
|
||||
#define STR_NAFFAT
|
||||
_ "Dune Burner" #enddef
|
||||
|
||||
#define STR_RAMI
|
||||
_ "Dune Rider" #enddef
|
||||
|
||||
#define STR_YOUNG_OGRE
|
||||
_ "Young Ogre" #enddef
|
||||
|
||||
#################################
|
||||
#textdomain wesnoth-multiplayer
|
||||
#################################
|
||||
|
||||
#define STR_DRAKES
|
||||
_ "Drakes" #enddef
|
||||
|
||||
#define STR_KNALGAN
|
||||
_ "Knalgan Alliance" #enddef
|
||||
|
||||
#define STR_LOYALISTS
|
||||
_ "Loyalists" #enddef
|
||||
|
||||
#define STR_NORTHERENS
|
||||
_ "Northerners" #enddef
|
||||
|
||||
#define STR_REBELS
|
||||
_ "Rebels" #enddef
|
||||
|
||||
#define STR_THE_UNDEAD
|
||||
_ "Undead" #enddef
|
BIN
data/campaigns/World_Conquest/images/misc/is_special.png
Normal file
After Width: | Height: | Size: 326 B |
BIN
data/campaigns/World_Conquest/images/misc/wct-blank.png
Normal file
After Width: | Height: | Size: 232 B |
BIN
data/campaigns/World_Conquest/images/misc/wct-blank2.png
Normal file
After Width: | Height: | Size: 232 B |
BIN
data/campaigns/World_Conquest/images/misc/wct-commander.png
Normal file
After Width: | Height: | Size: 496 B |
BIN
data/campaigns/World_Conquest/images/misc/wct-forge-mask.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/treehouse.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-crystal.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-crystal3.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-dolmen.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-dolmen2.png
Normal file
After Width: | Height: | Size: 8 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-oak-dead.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-oak-dead2.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-obelisk.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-outpost.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-temple.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-temple2.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-temple3.png
Normal file
After Width: | Height: | Size: 7 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-temple4.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-temple5.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
data/campaigns/World_Conquest/images/scenery/wct-tower.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
data/campaigns/World_Conquest/images/terrain/wct-crack-2.png
Normal file
After Width: | Height: | Size: 954 B |
BIN
data/campaigns/World_Conquest/images/terrain/wct-crack-3.png
Normal file
After Width: | Height: | Size: 905 B |
BIN
data/campaigns/World_Conquest/images/terrain/wct-crack-4.png
Normal file
After Width: | Height: | Size: 881 B |
BIN
data/campaigns/World_Conquest/images/terrain/wct-crack-5.png
Normal file
After Width: | Height: | Size: 826 B |
BIN
data/campaigns/World_Conquest/images/terrain/wct-crack-7.png
Normal file
After Width: | Height: | Size: 731 B |
BIN
data/campaigns/World_Conquest/images/terrain/wct-snowcrater1.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
data/campaigns/World_Conquest/images/terrain/wct-snowcrater2.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
data/campaigns/World_Conquest/images/terrain/wct-snowcrater3.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
data/campaigns/World_Conquest/images/terrain/wct-supply1.png
Normal file
After Width: | Height: | Size: 5 KiB |
BIN
data/campaigns/World_Conquest/images/terrain/wct-supply2.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
data/campaigns/World_Conquest/images/terrain/wct-supply3.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
41
data/campaigns/World_Conquest/lua/campaign/autorecall.lua
Normal file
|
@ -0,0 +1,41 @@
|
|||
local on_event = wesnoth.require("on_event")
|
||||
-- players get recalled by free all heroes up to castle size
|
||||
local function wc2_autorecall()
|
||||
for side_num = 1, wml.variables.wc2_player_count do
|
||||
local castle_tiles = wesnoth.get_locations {
|
||||
terrain = "C*",
|
||||
wml.tag["and"] {
|
||||
radius = 3,
|
||||
wml.tag.filter_radius {
|
||||
terrain = "C*,K*"
|
||||
},
|
||||
wml.tag.filter {
|
||||
side = side_num,
|
||||
canrecruit = true,
|
||||
}
|
||||
}
|
||||
}
|
||||
for i, loc in ipairs(castle_tiles) do
|
||||
wesnoth.wml_actions.recall {
|
||||
x = loc[1],
|
||||
y = loc[2],
|
||||
show = false,
|
||||
side = side_num,
|
||||
wml.tag.filter_wml {
|
||||
wml.tag.modifications {
|
||||
wml.tag.trait {
|
||||
id = "heroic"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
on_event("start", function(cx)
|
||||
local scenario_num = wc2_scenario.scenario_num()
|
||||
if (scenario_num or 1) > 1 then
|
||||
wc2_autorecall()
|
||||
end
|
||||
end)
|
120
data/campaigns/World_Conquest/lua/campaign/difficulty.lua
Normal file
|
@ -0,0 +1,120 @@
|
|||
-- The difficulty dialog. unlike other files this does not 'export' functions,
|
||||
-- just run this file to show the diffculty dialog.
|
||||
|
||||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local strings = {
|
||||
chose_difficulty = "<span size='large'>" .. _"Choose difficulty level:" .. "</span>",
|
||||
}
|
||||
|
||||
local _ = wesnoth.textdomain 'wesnoth-units'
|
||||
local strings_mainline = {
|
||||
Sergeant = _"Sergeant",
|
||||
Peasant = _"Peasant",
|
||||
Lieutenant = _"Lieutenant",
|
||||
General = _"General",
|
||||
Grand_Marshal = _"Grand Marshal"
|
||||
}
|
||||
|
||||
local function icon_human_difficult(unit_image, color)
|
||||
return "misc/blank-hex.png~SCALE(140,100)" ..
|
||||
"~BLIT(units/" .. unit_image .. ".png~RC(magenta>" .. color .. "),34,7)"
|
||||
end
|
||||
|
||||
local function str_dif_lvl(name)
|
||||
return "<span size='large'>" .. name .. "</span>"
|
||||
end
|
||||
|
||||
local icon_nightmare_difficulty = "units/monsters/fire-dragon.png~CROP(0,0,160,160)~RC(magenta>red)"
|
||||
|
||||
|
||||
local t_option = wml.tag.option
|
||||
|
||||
local function wct_difficulty(name, power, enemy_t, heroes, gold, train, exp)
|
||||
local nplayers = wml.variables.wc2_player_count
|
||||
if nplayers == 1 then
|
||||
heroes = heroes + 1
|
||||
end
|
||||
-- adjust bonus gold for number of players
|
||||
gold = gold * math.pow(2, 3 - nplayers)
|
||||
return wml.tag.command {
|
||||
wml.tag.set_variables {
|
||||
name = "wc2_difficulty",
|
||||
wml.tag.literal {
|
||||
name = name,
|
||||
enemy_power = power,
|
||||
enemy_trained = enemy_t,
|
||||
heroes = heroes,
|
||||
extra_gold = gold,
|
||||
extra_trainig = train,
|
||||
experience_penalty = exp,
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
function wct_scenario_chose_difficulty()
|
||||
-- fixme: should the first part argument of wct_difficulty be translatable
|
||||
wesnoth.wml_actions.message {
|
||||
speaker = "narrator",
|
||||
caption = strings.chose_difficulty,
|
||||
t_option {
|
||||
image = icon_human_difficult("human-peasants/peasant", "purple"),
|
||||
label = str_dif_lvl(strings_mainline.Peasant),
|
||||
description="(" .. _"Easy" .. ")",
|
||||
wct_difficulty("Peasant", 6, 2, 2, 10, true, 0),
|
||||
},
|
||||
t_option {
|
||||
image=icon_human_difficult("human-loyalists/sergeant", "black"),
|
||||
label=str_dif_lvl(strings_mainline.Sergeant),
|
||||
wct_difficulty("Sergeant", 7, 3, 2, 7, true, 5),
|
||||
},
|
||||
t_option {
|
||||
image=icon_human_difficult("human-loyalists/lieutenant", "brown"),
|
||||
label=str_dif_lvl(strings_mainline.Lieutenant),
|
||||
wct_difficulty("Lieutenant", 8, 4, 2, 5, true, 10),
|
||||
},
|
||||
t_option {
|
||||
image=icon_human_difficult("human-loyalists/general", "orange"),
|
||||
label=str_dif_lvl(strings_mainline.General),
|
||||
wct_difficulty("General", 8, 5, 2, 2, false, 13),
|
||||
},
|
||||
t_option {
|
||||
image=icon_human_difficult("human-loyalists/marshal", "white"),
|
||||
label=str_dif_lvl(strings_mainline.Grand_Marshal),
|
||||
wct_difficulty("Grand_marshal", 9, 6, 2, 1, false, 17),
|
||||
},
|
||||
t_option {
|
||||
image=icon_nightmare_difficulty,
|
||||
label=str_dif_lvl("Nightmare"),
|
||||
description="(" .. _"Expert" .. ")",
|
||||
wct_difficulty("Nightmare", 9, 7, 1, 0, false, 20),
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function wct_scenario_start_bonus()
|
||||
for side_num = 1, wml.variables.wc2_player_count do
|
||||
wesnoth.wml_actions.wc2_start_units {
|
||||
side = side_num
|
||||
}
|
||||
end
|
||||
|
||||
if wml.variables.wc2_difficulty.extra_trainig then
|
||||
for side_num = 1, wml.variables.wc2_player_count do
|
||||
wesnoth.wml_actions.wc2_give_random_training {
|
||||
among="2,3,4,5,6",
|
||||
side = side_num,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function wesnoth.wml_actions.wc2_choose_difficulty(cfg)
|
||||
if wml.variables["wc2_difficulty"] then
|
||||
return
|
||||
end
|
||||
wct_scenario_chose_difficulty()
|
||||
wct_scenario_start_bonus()
|
||||
wesnoth.fire_event("wc2_start")
|
||||
end
|
299
data/campaigns/World_Conquest/lua/campaign/enemy.lua
Normal file
|
@ -0,0 +1,299 @@
|
|||
local on_event = wesnoth.require("on_event")
|
||||
local helper = wesnoth.require("helper")
|
||||
|
||||
local enemy = {}
|
||||
|
||||
local function get_advanced_units(level, list, res)
|
||||
res = res or {}
|
||||
-- guards against units that can advance in circles or to themselves
|
||||
res_set = {}
|
||||
local add_units = function(units)
|
||||
for unused, typename in ipairs(units) do
|
||||
local unittype = wesnoth.unit_types[typename]
|
||||
if unittype.level == level then
|
||||
table.insert(res, typename)
|
||||
elseif not res_set[typename] then
|
||||
res_set[typename] = true;
|
||||
add_units(unittype.advances_to)
|
||||
end
|
||||
end
|
||||
end
|
||||
add_units(list)
|
||||
return res
|
||||
end
|
||||
|
||||
function enemy.pick_suitable_enemy_item(unit)
|
||||
local enemy_items = wc2_utils.split_to_array(wml.variables["wc2_enemy_army.artifacts"])
|
||||
if #enemy_items == 0 then
|
||||
enemy_items = wc2_artifacts.fresh_artifacts_list("enemy")
|
||||
end
|
||||
-- list of indexes to enemy_items
|
||||
local possible_artifacts = {}
|
||||
for i, v in ipairs(enemy_items) do
|
||||
local filter = wml.get_child(wc2_artifacts.get_artifact(tonumber(v)), "filter")
|
||||
if not filter or unit:matches(filter) then
|
||||
table.insert(possible_artifacts, i)
|
||||
end
|
||||
end
|
||||
if #possible_artifacts == 0 then
|
||||
return
|
||||
end
|
||||
local i = possible_artifacts[wesnoth.random(#possible_artifacts)]
|
||||
local artifact_id = tonumber(enemy_items[i])
|
||||
table.remove(enemy_items, i)
|
||||
wml.variables["wc2_enemy_army.artifacts"] = table.concat(enemy_items, ",")
|
||||
return artifact_id
|
||||
end
|
||||
|
||||
|
||||
-- todo the old code used prerecruit to allow artifact events written into unit become active in recruit, why?
|
||||
on_event("recruit", function(ec)
|
||||
if wesnoth.current.turn < 2 then
|
||||
--the old code also didn't gave items on first turn.
|
||||
return
|
||||
end
|
||||
local side_variables = wesnoth.sides[wesnoth.current.side].variables
|
||||
local needs_item = side_variables["wc2.random_items"] or 0
|
||||
local scenario_num = wc2_scenario.scenario_num()
|
||||
if needs_item == 0 then
|
||||
return
|
||||
end
|
||||
side_variables["wc2.random_items"] = needs_item - 1
|
||||
local unit = wesnoth.get_unit(ec.x1, ec.y1)
|
||||
local item_id = enemy.pick_suitable_enemy_item(unit)
|
||||
wc2_artifacts.give_item(unit, item_id, false)
|
||||
if true then
|
||||
unit.experience = unit.experience + scenario_num * (16 + wml.variables["wc2_difficulty.enemy_power"])
|
||||
unit:advance(true, true)
|
||||
end
|
||||
wesnoth.allow_undo(false)
|
||||
end)
|
||||
|
||||
--Gives the enemy side @cfg.side a commander (a hero unit)
|
||||
function enemy.do_commander(cfg, group_id, loc)
|
||||
if not cfg.commander or cfg.commander <= 0 then
|
||||
return
|
||||
end
|
||||
local scenario = wc2_scenario.scenario_num()
|
||||
--wesnoth.message("do_commander", wml.variables[("wc2_enemy_army.group[%d].allies_available"):format(group_id)])
|
||||
local ally_i = wc2_utils.pick_random(("wc2_enemy_army.group[%d].allies_available"):format(group_id)) - 1
|
||||
local leader_index = wesnoth.random(wml.variables[("wc2_enemy_army.group[%d].leader.length"):format(ally_i)]) - 1
|
||||
local new_recruits = wml.variables[("wc2_enemy_army.group[%d].leader[%d].recruit"):format(ally_i, leader_index)]
|
||||
wesnoth.wml_actions.allow_recruit {
|
||||
side = cfg.side,
|
||||
type = new_recruits
|
||||
}
|
||||
local commander_options = wml.variables[("wc2_enemy_army.group[%d].commander.level%d"):format(ally_i, cfg.commander)]
|
||||
wesnoth.wml_actions.unit {
|
||||
x = loc[1],
|
||||
y = loc[2],
|
||||
type = helper.rand(commander_options),
|
||||
side = cfg.side,
|
||||
generate_name = true,
|
||||
role = "commander",
|
||||
experience = scenario * ((wml.variables["wc2_difficulty.enemy_power"] or 6) - 7 + cfg.commander),
|
||||
wml.tag.modifications {
|
||||
wc2_heroes.commander_overlay_object(),
|
||||
wml.tag.trait(wc2_heroes.trait_heroic),
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
-- WORLD_CONQUEST_TEK_ENEMY_SUPPLY
|
||||
function enemy.do_supply(cfg, group_id, loc)
|
||||
if not (cfg.supply == 1) then
|
||||
return
|
||||
end
|
||||
local u = wesnoth.get_unit(loc[1], loc[2])
|
||||
u:add_modification("trait", wc2_heroes.trait_expert)
|
||||
|
||||
wesnoth.wml_actions.event {
|
||||
name = "side " .. cfg.side .. " turn 2",
|
||||
wml.tag.wc2_map_supply_village {
|
||||
x = u.x,
|
||||
y = u.y,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
-- WORLD_CONQUEST_TEK_ENEMY_RECALLS
|
||||
on_event("recruit", function(ec)
|
||||
local side_num = wesnoth.current.side
|
||||
local side_variables = wesnoth.sides[side_num].variables
|
||||
local to_recall = wc2_utils.split_to_array(side_variables["wc2.to_recall"] or "")
|
||||
if #to_recall == 0 then
|
||||
return
|
||||
end
|
||||
local candidates = wesnoth.get_locations {
|
||||
terrain = "K*,C*,*^C*,*^K*",
|
||||
wml.tag["and"] {
|
||||
wml.tag.filter {
|
||||
canrecruit = true,
|
||||
side = side_num,
|
||||
wml.tag.filter_location {
|
||||
terrain = "K*^*,*^K*",
|
||||
},
|
||||
},
|
||||
radius = 999,
|
||||
wml.tag.filter_radius {
|
||||
terrain = "K*^*,C*^*,*^K*,*^C*",
|
||||
},
|
||||
},
|
||||
wml.tag["not"] {
|
||||
wml.tag.filter {}
|
||||
}
|
||||
}
|
||||
helper.shuffle(candidates)
|
||||
while #candidates > 0 and #to_recall > 0 do
|
||||
enemy.fake_recall(side_num, to_recall[1], candidates[1])
|
||||
table.remove(to_recall, 1)
|
||||
table.remove(candidates, 1)
|
||||
end
|
||||
side_variables["wc2.to_recall"] = table.concat(to_recall, ",")
|
||||
end)
|
||||
|
||||
--Gives the enemy side @cfg.side units that it can recall.
|
||||
--It does not really addthem to the recall list but
|
||||
--emulates that by placing higher level units on the map in that sides
|
||||
function enemy.do_recall(cfg, group_id, loc)
|
||||
local side_num = cfg.side
|
||||
local side_variables = wesnoth.sides[side_num].variables
|
||||
|
||||
local group = wml.variables[("wc2_enemy_army.group[%d]"):format(group_id)]
|
||||
local to_recall = wc2_utils.split_to_array(side_variables["wc2.to_recall"])
|
||||
local function recall_level(level)
|
||||
local amount = wml.get_child(cfg, "recall")["level" .. level] or 0
|
||||
local types = wc2_utils.split_to_array(wml.get_child(group, "recall")["level" .. level] or "")
|
||||
if #types == 0 then
|
||||
get_advanced_units(level, wc2_utils.split_to_array(group.recruit), types)
|
||||
end
|
||||
for i = 1, amount do
|
||||
table.insert(to_recall, types[wesnoth.random(#types)])
|
||||
end
|
||||
end
|
||||
recall_level(2)
|
||||
recall_level(3)
|
||||
side_variables["wc2.to_recall"] = table.concat(to_recall, ",")
|
||||
end
|
||||
|
||||
-- WCT_ENEMY_FAKE_RECALL
|
||||
function enemy.fake_recall(side_num, t, loc)
|
||||
local side = wesnoth.sides[side_num]
|
||||
local u = wesnoth.create_unit {
|
||||
side = side_num,
|
||||
type = t,
|
||||
generate_name = true,
|
||||
moves = 0,
|
||||
}
|
||||
wc2_training.apply(u)
|
||||
u:to_map(loc)
|
||||
side.gold = side.gold - 20
|
||||
end
|
||||
|
||||
|
||||
-- WORLD_CONQUEST_TEK_ENEMY_TRAINING
|
||||
function enemy.do_training(cfg, group_id, loc)
|
||||
local tr = cfg.trained or 0
|
||||
local dif = wml.variables["wc2_difficulty.enemy_trained"] or 0
|
||||
if tr ~= 0 and dif >= tr then
|
||||
--enemy can only get Melee, Ranger, Health or Movement
|
||||
wesnoth.wml_actions.wc2_give_random_training {
|
||||
side = cfg.side,
|
||||
among="2,3,4,6"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function enemy.do_gold(cfg, side)
|
||||
--difficulty_enemy_power is in [6,9]
|
||||
local enemy_power = (wml.variables["wc2_difficulty.enemy_power"] or 6)
|
||||
local factor = (cfg.nplayers + 1 ) * enemy_power/6 - 2
|
||||
side.gold = side.gold + cfg.bonus_gold * factor
|
||||
end
|
||||
|
||||
function enemy.init_data()
|
||||
if wml.variables.wc2_enemy_army == nil then
|
||||
-- give eras an option to overwrite the enemy data.
|
||||
wesnoth.fire_event("wc2_init_enemy")
|
||||
end
|
||||
if wml.variables.wc2_enemy_army == nil then
|
||||
-- give eras an option to overwrite the enemy data.
|
||||
local enemy_army = wesnoth.dofile("./enemy_data.lua")
|
||||
wml.variables.wc2_enemy_army = wc2_convert.lon_to_wml(enemy_army, "wct_enemy")
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
called like
|
||||
[wc2_enemy]
|
||||
side={SIDE}
|
||||
##the level of the commander.
|
||||
commander={COM}
|
||||
have_item={ITEM}
|
||||
trained={TRAIN}
|
||||
supply={SUP}
|
||||
[recall]
|
||||
level2={L2}
|
||||
level3={L3}
|
||||
[/recall]
|
||||
[/wc2_enemy]
|
||||
--]]
|
||||
function wesnoth.wml_actions.wc2_enemy(cfg)
|
||||
enemy.init_data()
|
||||
local side_num = cfg.side
|
||||
local side = wesnoth.sides[side_num]
|
||||
local scenario = wc2_scenario.scenario_num()
|
||||
|
||||
enemy.do_gold(cfg, side)
|
||||
|
||||
local dummy_unit = wesnoth.get_units({side = side_num, canrecruit = true})[1]
|
||||
local loc = {dummy_unit.x,dummy_unit.y}
|
||||
dummy_unit:erase()
|
||||
local enemy_type_id = wc2_utils.pick_random("wc2_enemy_army.factions_available") - 1
|
||||
if enemy_type_id == nil then
|
||||
--should't happen, added for robustness.
|
||||
local n_groups = wml.variables["wc2_enemy_army.group.length"]
|
||||
if n_groups > 0 then
|
||||
enemy_type_id = wesnoth.random(n_groups) - 1
|
||||
else
|
||||
error("no enemy groups defined")
|
||||
end
|
||||
end
|
||||
local leader_cfg = wc2_utils.pick_random_t(("wc2_enemy_army.group[%d].leader"):format(enemy_type_id))
|
||||
local unit = wesnoth.create_unit {
|
||||
x = loc[1],
|
||||
y = loc[2],
|
||||
type = scenario == 1 and leader_cfg.level2 or leader_cfg.level3,
|
||||
side = side_num,
|
||||
canrecruit = true,
|
||||
generate_name = true,
|
||||
max_moves = 0,
|
||||
wml.tag.modifications { wml.tag.trait(wc2_heroes.trait_heroic) },
|
||||
}
|
||||
if unit.name == "" then
|
||||
-- give names to undead
|
||||
unit.name = wc2_random_names.generate()
|
||||
end
|
||||
unit:to_map()
|
||||
wesnoth.wml_actions.set_recruit {
|
||||
side = side_num,
|
||||
recruit = wml.variables[("wc2_enemy_army.group[%d].recruit"):format(enemy_type_id)]
|
||||
}
|
||||
wesnoth.wml_actions.allow_recruit {
|
||||
side = side_num,
|
||||
type = leader_cfg.recruit
|
||||
}
|
||||
|
||||
enemy.do_training(cfg, enemy_type_id, loc)
|
||||
enemy.do_commander(cfg, enemy_type_id, loc)
|
||||
enemy.do_supply(cfg, enemy_type_id, loc)
|
||||
enemy.do_recall(cfg, enemy_type_id, loc)
|
||||
-- todo: remove or uncomment (i think this was moved to scenario generation)
|
||||
-- side.gold = side.gold + wml.variables["enemy_army.bonus_gold"]
|
||||
if cfg.have_item > 0 and cfg.have_item <= (wml.variables["wc2_difficulty.enemy_power"] or 6) then
|
||||
side.variables["wc2.random_items"] = 1
|
||||
end
|
||||
end
|
||||
|
||||
return enemy
|
322
data/campaigns/World_Conquest/lua/campaign/enemy_data.lua
Normal file
|
@ -0,0 +1,322 @@
|
|||
|
||||
-- The rules for enemy recruitlist are as follows:
|
||||
-- each side Has a 'faction' (here: group) a leader from that faction and maybe a leader from another faction.
|
||||
-- the enemy side can then recruit all units from its faction and from all it's leaders, that why having
|
||||
-- unit {recruit= that are already contained in {recruit= is not redundant.
|
||||
local enemy_army = {}
|
||||
enemy_army.group = {
|
||||
{
|
||||
id = "northerners",
|
||||
recruit = {"Orcish Grunt","Orcish Archer","Wolf Rider","Orcish Assassin","Troll Whelp"},
|
||||
recall = {
|
||||
level2 = {"Orcish Ruler","Orcish Slayer","Orcish Crossbowman","Troll Rocklobber","Troll","Orcish Warrior","Goblin Pillager","Goblin Knight","Orcish Crossbowman","Troll","Orcish Warrior","Troll Hero"},
|
||||
level3 = {"Orcish Warlord","Troll Warrior","Orcish Slurbow","Orcish Sovereign","Direwolf Rider","Orcish Warlord","Troll Warrior","Orcish Slurbow","Great Troll","Direwolf Rider"},
|
||||
},
|
||||
commander = {
|
||||
level1 = {"Orcish Leader","Orcish Grunt","Orcish Archer","Orcish Assassin"},
|
||||
level2 = {"Orcish Ruler","Troll Hero","Orcish Slayer","Orcish Crossbowman","Troll Rocklobber","Troll","Orcish Warrior"},
|
||||
level3 = {"Orcish Warlord","Troll Warrior","Orcish Slurbow","Orcish Sovereign","Great Troll"},
|
||||
},
|
||||
leader = {
|
||||
{
|
||||
level2 = "Orcish Warrior",
|
||||
level3 = "Orcish Warlord",
|
||||
recruit = {"Orcish Grunt","Orcish Archer","Wolf Rider","Orcish Assassin"},
|
||||
},
|
||||
{
|
||||
level2 = "Troll",
|
||||
level3 = "Troll Warrior",
|
||||
recruit = {"Orcish Grunt","Orcish Archer","Orcish Assassin","Troll Whelp"},
|
||||
},
|
||||
{
|
||||
level2 = "Troll Rocklobber",
|
||||
level3 = "Great Troll",
|
||||
recruit = {"Orcish Grunt","Orcish Assassin","Wolf Rider","Troll Whelp"},
|
||||
},
|
||||
{
|
||||
level2 = "Orcish Crossbowman",
|
||||
level3 = "Orcish Slurbow",
|
||||
recruit = {"Orcish Grunt","Orcish Archer","Wolf Rider","Orcish Assassin"},
|
||||
},
|
||||
{
|
||||
level2 = "Orcish Slayer",
|
||||
level3 = "Naga Myrmidon",
|
||||
recruit = {"Orcish Grunt","Orcish Archer","Wolf Rider","Orcish Assassin","Naga Fighter"},
|
||||
},
|
||||
{
|
||||
level2 = "Goblin Knight",
|
||||
level3 = "Direwolf Rider",
|
||||
recruit = {"Goblin Spearman","Orcish Leader","Wolf Rider","Orcish Archer","Troll Whelp"},
|
||||
},
|
||||
{
|
||||
level2 = "Orcish Ruler",
|
||||
level3 = "Orcish Sovereign",
|
||||
recruit = {"Orcish Grunt","Orcish Leader","Wolf Rider","Orcish Archer"},
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "loyalists",
|
||||
recruit = {"Spearman","Bowman","Cavalryman","Fencer","Mage"},
|
||||
recall = {
|
||||
level2 = {"White Mage","Red Mage","Duelist","Longbowman","Shock Trooper","Pikeman","Swordsman","Lieutenant","Dragoon","Knight","Javelineer","Pikeman","Swordsman","Longbowman"},
|
||||
level3 = {"General","Halberdier","Royal Guard","Silver Mage","Iron Mauler","Master Bowman","Master at Arms","Arch Mage","Mage of Light","Paladin","Grand Knight","Cavalier","General","Halberdier","Royal Guard","Iron Mauler","Master Bowman","Master at Arms"},
|
||||
},
|
||||
commander = {
|
||||
level1 = {"Sergeant","Spearman","Bowman","Mage","Fencer","Heavy Infantryman"},
|
||||
level2 = {"White Mage","Red Mage","Duelist","Longbowman","Shock Trooper","Pikeman","Swordsman","Lieutenant","Javelineer"},
|
||||
level3 = {"General","Halberdier","Royal Guard","Silver Mage","Iron Mauler","Master Bowman","Master at Arms","Arch Mage","Mage of Light"},
|
||||
},
|
||||
leader = {
|
||||
{
|
||||
level2 = "Lieutenant",
|
||||
level3 = "General",
|
||||
recruit = {"Spearman","Bowman","Cavalryman","Fencer","Mage"},
|
||||
},
|
||||
{
|
||||
level2 = "Swordsman",
|
||||
level3 = "Royal Guard",
|
||||
recruit = {"Spearman","Bowman","Cavalryman","Heavy Infantryman","Mage"},
|
||||
},
|
||||
{
|
||||
level2 = "Pikeman",
|
||||
level3 = "Halberdier",
|
||||
recruit = {"Spearman","Bowman","Cavalryman","Horseman","Mage"},
|
||||
},
|
||||
{
|
||||
level2 = "Javelineer",
|
||||
level3 = "Silver Mage",
|
||||
recruit = {"Spearman","Bowman","Horseman","Fencer","Mage"},
|
||||
},
|
||||
{
|
||||
level2 = "Shock Trooper",
|
||||
level3 = "Iron Mauler",
|
||||
recruit = {"Spearman","Mage","Cavalryman","Heavy Infantryman"},
|
||||
},
|
||||
{
|
||||
level2 = "Longbowman",
|
||||
level3 = "Master Bowman",
|
||||
recruit = {"Spearman","Bowman","Cavalryman","Horseman","Heavy Infantryman"},
|
||||
},
|
||||
{
|
||||
level2 = "Duelist",
|
||||
level3 = "Master at Arms",
|
||||
recruit = {"Spearman","Bowman","Cavalryman","Fencer","Mage"},
|
||||
},
|
||||
{
|
||||
level2 = "Red Mage",
|
||||
level3 = "Arch Mage",
|
||||
recruit = {"Spearman","Bowman","Mage","Cavalryman","Heavy Infantryman"},
|
||||
},
|
||||
{
|
||||
level2 = "White Mage",
|
||||
level3 = "Mage of Light",
|
||||
recruit = {"Spearman","Heavy Infantryman","Cavalryman","Mage","Bowman"},
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "elves",
|
||||
recruit = {"Elvish Fighter","Elvish Archer","Elvish Shaman","Elvish Scout","Wose"},
|
||||
recall = {
|
||||
level2 = {"Elder Wose","Elvish Sorceress","Elvish Druid","Elvish Marksman","Elvish Ranger","Elvish Hero","Elvish Captain","Elvish Rider","Elder Wose","Elvish Hero","Elder Wose","Elvish Sorceress","Red Mage","Elvish Marksman","Elvish Ranger","Elvish Hero","Elvish Captain","Elvish Rider","Elvish Ranger","Elvish Hero"},
|
||||
level3 = {"Elvish Marshal","Elvish Champion","Elvish Avenger","Elvish Sharpshooter","Elvish Shyde","Elvish Enchantress","Ancient Wose","Elvish Outrider","Ancient Wose","Elvish Champion","Elvish Marshal","Elvish Champion","Elvish Avenger","Elvish Sharpshooter","Arch Mage","Elvish Enchantress","Ancient Wose","Elvish Outrider","Elvish Avenger","Elvish Champion"},
|
||||
},
|
||||
commander = {
|
||||
level1 = {"Elvish Shaman","Elvish Fighter","Elvish Archer","Wose"},
|
||||
level2 = {"Elder Wose","Elvish Sorceress","Elvish Druid","Elvish Marksman","Elvish Ranger","Elvish Hero","Elvish Captain","Elvish Lord"},
|
||||
level3 = {"Elvish Marshal","Elvish Champion","Elvish Avenger","Elvish Sharpshooter","Elvish Shyde","Elvish Enchantress","Ancient Wose","Arch Mage","Elvish High Lord"},
|
||||
},
|
||||
leader = {
|
||||
{
|
||||
level2 = "Elvish Captain",
|
||||
level3 = "Elvish Marshal",
|
||||
recruit = {"Elvish Fighter","Elvish Archer","Elvish Shaman","Elvish Scout"},
|
||||
},
|
||||
{
|
||||
level2 = "Elvish Hero",
|
||||
level3 = "Elvish Champion",
|
||||
recruit = {"Elvish Fighter","Elvish Archer","Elvish Shaman","Elvish Scout"},
|
||||
},
|
||||
{
|
||||
level2 = "Elvish Ranger",
|
||||
level3 = "Elvish Avenger",
|
||||
recruit = {"Elvish Fighter","Elvish Archer","Wose","Elvish Scout"},
|
||||
},
|
||||
{
|
||||
level2 = "Elvish Marksman",
|
||||
level3 = "Elvish Sharpshooter",
|
||||
recruit = {"Elvish Fighter","Elvish Archer","Mage","Elvish Scout"},
|
||||
},
|
||||
{
|
||||
level2 = "Elvish Druid",
|
||||
level3 = "Elvish Shyde",
|
||||
recruit = {"Elvish Fighter","Elvish Archer","Elvish Shaman","Wose"},
|
||||
},
|
||||
{
|
||||
level2 = "Elvish Sorceress",
|
||||
level3 = "Elvish Enchantress",
|
||||
recruit = {"Elvish Fighter","Elvish Archer","Elvish Shaman","Elvish Scout","Mage"},
|
||||
},
|
||||
{
|
||||
level2 = "Elder Wose",
|
||||
level3 = "Ancient Wose",
|
||||
recruit = {"Elvish Shaman","Elvish Fighter","Mage"," Wose"},
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "knalgans",
|
||||
recruit = {"Dwarvish Fighter","Dwarvish Thunderer","Thief","Footpad","Poacher"},
|
||||
recall = {
|
||||
level2 = {"Dwarvish Stalwart","Dwarvish Thunderguard","Dwarvish Steelclad","Rogue","Trapper","Gryphon Master","Bandit","Outlaw","Dwarvish Stalwart","Dwarvish Thunderguard","Dwarvish Steelclad","Dwarvish Berserker"},
|
||||
level3 = {"Dwarvish Lord","Dwarvish Dragonguard","Dwarvish Sentinel","Assassin","Huntsman","Fugitive","Highwayman","Dwarvish Lord","Dwarvish Dragonguard","Dwarvish Sentinel"},
|
||||
},
|
||||
commander = {
|
||||
level1 = {"Dwarvish Thunderer","Dwarvish Fighter","Dwarvish Guardsman","Dwarvish Scout","Thief","Poacher"},
|
||||
level2 = {"Dwarvish Stalwart","Dwarvish Thunderguard","Dwarvish Steelclad","Dwarvish Pathfinder","Rogue","Trapper"},
|
||||
level3 = {"Dwarvish Lord","Dwarvish Dragonguard","Dwarvish Sentinel","Assassin","Huntsman","Highwayman","Dwarvish Explorer"},
|
||||
},
|
||||
leader = {
|
||||
{
|
||||
level2 = "Dwarvish Steelclad",
|
||||
level3 = "Dwarvish Lord",
|
||||
recruit = {"Dwarvish Fighter","Dwarvish Thunderer","Dwarvish Ulfserker","Dwarvish Guardsman"},
|
||||
},
|
||||
{
|
||||
level2 = "Dwarvish Thunderguard",
|
||||
level3 = "Dwarvish Dragonguard",
|
||||
recruit = {"Dwarvish Fighter","Dwarvish Thunderer","Gryphon Rider","Poacher"},
|
||||
},
|
||||
{
|
||||
level2 = "Dwarvish Stalwart",
|
||||
level3 = "Dwarvish Sentinel",
|
||||
recruit = {"Footpad","Dwarvish Thunderer","Gryphon Rider","Dwarvish Guardsman"},
|
||||
},
|
||||
{
|
||||
level2 = "Rogue",
|
||||
level3 = "Assassin",
|
||||
recruit = {"Thug","Thief","Footpad","Dwarvish Ulfserker","Gryphon Rider"},
|
||||
},
|
||||
{
|
||||
level2 = "Trapper",
|
||||
level3 = "Huntsman",
|
||||
recruit = {"Thug","Thief","Poacher","Dwarvish Fighter","Dwarvish Thunderer"},
|
||||
},
|
||||
{
|
||||
level2 = "Bandit",
|
||||
level3 = "Highwayman",
|
||||
recruit = {"Thug","Thief","Dwarvish Thunderer","Dwarvish Ulfserker","Dwarvish Fighter"},
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "drakes",
|
||||
recruit = {"Drake Fighter","Drake Clasher","Drake Glider","Drake Burner","Saurian Augur"},
|
||||
recall = {
|
||||
level2 = {"Drake Arbiter","Drake Thrasher","Drake Warrior","Fire Drake","Drake Flare","Saurian Oracle","Saurian Soothsayer","Saurian Ambusher","Drake Warrior","Drake Thrasher","Sky Drake"},
|
||||
level3 = {"Drake Flameheart","Inferno Drake","Drake Blademaster","Drake Blademaster","Drake Enforcer","Drake Warden","Saurian Flanker","Saurian Flanker","Hurricane Drake"},
|
||||
},
|
||||
commander = {
|
||||
level1 = {"Drake Burner","Drake Fighter","Drake Clasher","Saurian Augur","Saurian Skirmisher"},
|
||||
level2 = {"Drake Arbiter","Drake Thrasher","Drake Warrior","Fire Drake","Drake Flare","Saurian Ambusher","Saurian Oracle"},
|
||||
level3 = {"Drake Flameheart","Inferno Drake","Drake Blademaster","Drake Enforcer","Drake Warden","Saurian Flanker"},
|
||||
},
|
||||
leader = {
|
||||
{
|
||||
level2 = "Drake Flare",
|
||||
level3 = "Drake Flameheart",
|
||||
recruit = {"Drake Fighter","Drake Clasher","Drake Glider","Drake Burner"},
|
||||
},
|
||||
{
|
||||
level2 = "Fire Drake",
|
||||
level3 = "Inferno Drake",
|
||||
recruit = {"Drake Fighter","Saurian Augur","Drake Glider","Drake Burner"},
|
||||
},
|
||||
{
|
||||
level2 = "Drake Warrior",
|
||||
level3 = "Drake Blademaster",
|
||||
recruit = {"Drake Fighter","Saurian Skirmisher","Drake Glider","Drake Burner"},
|
||||
},
|
||||
{
|
||||
level2 = "Drake Thrasher",
|
||||
level3 = "Drake Enforcer",
|
||||
recruit = {"Drake Fighter","Drake Clasher","Saurian Skirmisher","Drake Burner"},
|
||||
},
|
||||
{
|
||||
level2 = "Drake Arbiter",
|
||||
level3 = "Drake Warden",
|
||||
recruit = {"Saurian Skirmisher","Drake Clasher","Drake Glider","Drake Burner"},
|
||||
},
|
||||
{
|
||||
level2 = "Saurian Oracle",
|
||||
level3 = "Saurian Flanker",
|
||||
recruit = {"Saurian Skirmisher","Saurian Augur","Drake Clasher","Drake Burner"},
|
||||
},
|
||||
{
|
||||
level2 = "Saurian Soothsayer",
|
||||
level3 = "Hurricane Drake",
|
||||
recruit = {"Saurian Skirmisher","Saurian Augur","Drake Glider","Drake Fighter"},
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "undead",
|
||||
recruit = {"Skeleton","Skeleton Archer","Ghost","Ghoul","Dark Adept"},
|
||||
recall = {
|
||||
level2 = {"Revenant","Deathblade","Bone Shooter","Dark Sorcerer","Necrophage","Wraith","Shadow","Revenant","Bone Shooter","Dark Sorcerer","Necrophage","Chocobone"},
|
||||
level3 = {"Draug","Death Knight","Necromancer","Lich","Ghast","Banebow","Spectre","Nightgaunt","Draug","Ghast","Banebow"},
|
||||
},
|
||||
commander = {
|
||||
level1 = {"Dark Adept","Skeleton Archer","Skeleton","Ghoul"},
|
||||
level2 = {"Revenant","Deathblade","Bone Shooter","Dark Sorcerer","Necrophage"},
|
||||
level3 = {"Draug","Death Knight","Necromancer","Lich","Ghast","Banebow"},
|
||||
},
|
||||
leader = {
|
||||
{
|
||||
level2 = "Revenant",
|
||||
level3 = "Draug",
|
||||
recruit = {"Skeleton","Skeleton Archer","Ghost","Ghoul"},
|
||||
},
|
||||
{
|
||||
level2 = "Deathblade",
|
||||
level3 = "Death Knight",
|
||||
recruit = {"Skeleton","Skeleton Archer","Dark Adept","Ghoul"},
|
||||
},
|
||||
{
|
||||
level2 = "Bone Shooter",
|
||||
level3 = "Banebow",
|
||||
recruit = {"Skeleton","Skeleton Archer","Ghost","Ghoul"},
|
||||
},
|
||||
{
|
||||
level2 = "Dark Sorcerer",
|
||||
level3 = "Lich",
|
||||
recruit = {"Skeleton Archer","Dark Adept","Ghoul","Vampire Bat"},
|
||||
},
|
||||
{
|
||||
level2 = "Necrophage",
|
||||
level3 = "Ghast",
|
||||
recruit = {"Skeleton","Dark Adept","Ghoul","Ghost"},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
enemy_army.factions_available = {}
|
||||
-- each faction can be picked up to 4 times along campaign
|
||||
for i = 1, #enemy_army.group do
|
||||
for j = 1, 4 do
|
||||
table.insert(enemy_army.factions_available, i)
|
||||
end
|
||||
end
|
||||
-- each faction pick any faction as ally just 1 time
|
||||
for i = 1, #enemy_army.group do
|
||||
local ally = {}
|
||||
enemy_army.group[i].allies_available = ally
|
||||
for j = 1, #enemy_army.group do
|
||||
if j ~= i then
|
||||
table.insert(ally, j)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return enemy_army
|
98
data/campaigns/World_Conquest/lua/campaign/enemy_themed.lua
Normal file
|
@ -0,0 +1,98 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local on_event = wesnoth.require("on_event")
|
||||
|
||||
local strings = {
|
||||
enemy_pet = _ "$name|'s pet"
|
||||
}
|
||||
-- in the later scenarios there is a small chance that a scenario will be themed for an enemy
|
||||
-- which means in paticular changing the castle of the enemy accorign to the unit type of that
|
||||
-- enemy, and giving him an extra unit.
|
||||
local function wct_map_enemy_themed(race, pet, castle, village, chance)
|
||||
if wesnoth.random(100) > chance then
|
||||
return
|
||||
end
|
||||
local boss = wesnoth.get_units {
|
||||
side="4,5,6,7,8,9",
|
||||
canrecruit=true,
|
||||
race=race,
|
||||
-- human means only outlaw
|
||||
wml.tag["not"] {
|
||||
race="human",
|
||||
wml.tag["not"] {
|
||||
wml.tag.filter_wml {
|
||||
alignment="chaotic",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
boss = boss[1]
|
||||
if boss == nil then
|
||||
return
|
||||
end
|
||||
--give themed castle
|
||||
wesnoth.set_terrain(boss.loc, "K" .. castle, "base")
|
||||
wesnoth.wml_actions.terrain {
|
||||
terrain="C" .. castle,
|
||||
wml.tag["and"] {
|
||||
terrain = "C*,*^C*",
|
||||
wml.tag["and"] {
|
||||
wml.tag.filter {
|
||||
x=boss.x,
|
||||
y=boss.y,
|
||||
},
|
||||
radius=999,
|
||||
wml.tag.filter_radius {
|
||||
terrain="K*^*,C*^*,*^K*,*^C*"
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
local elvish_castle = wesnoth.get_locations {
|
||||
terrain="Cv",
|
||||
wml.tag.filter_adjacent_location {
|
||||
terrain="Kv^*"
|
||||
}
|
||||
}
|
||||
-- extra tweak with trees to elvish castle
|
||||
for i, tile in ipairs(elvish_castle) do
|
||||
if wesnoth.random(10) <= 4 then
|
||||
wesnoth.set_terrain(tile, "Cv^Fet")
|
||||
end
|
||||
end
|
||||
-- adjacent themed villages
|
||||
wesnoth.wml_actions.terrain {
|
||||
terrain=village,
|
||||
wml.tag["and"] {
|
||||
terrain="*^V*",
|
||||
wml.tag.filter_adjacent_location {
|
||||
terrain="C" .. castle .. ",K" .. castle .. "^*",
|
||||
},
|
||||
},
|
||||
}
|
||||
-- give pet
|
||||
wesnoth.wml_actions.unit {
|
||||
x = boss.x,
|
||||
y = boss.y,
|
||||
type=pet,
|
||||
side = boss.side,
|
||||
name= wesnoth.format(enemy_pet, { name = boss.name }),
|
||||
role = "hero",
|
||||
overlays = "misc/hero-icon.png",
|
||||
wml.tag.modifications {
|
||||
wc2_heroes.trait_heroic,
|
||||
wc2_heroes.trait_expert,
|
||||
wml.tag.object {
|
||||
id = "wc2_hero_overlay",
|
||||
wml.tag.effect {
|
||||
apply_to="overlay",
|
||||
add = "misc/hero-icon.png",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function wesnoth.wml_actions.wc2_enemy_themed(cfg)
|
||||
wct_map_enemy_themed(cfg.race, cfg.pet, cfg.castle, cfg.village, cfg.chance)
|
||||
end
|
35
data/campaigns/World_Conquest/lua/campaign/objectives.lua
Normal file
|
@ -0,0 +1,35 @@
|
|||
--creates the objectives of the wc2 scenarios.
|
||||
|
||||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local strings = {
|
||||
wct_victory_condition = _"Defeat all enemy leaders and commanders",
|
||||
turns = _"Turns run out",
|
||||
wct_defeat_condition = _ "Lose your leader and all your commanders",
|
||||
difficulty = "Difficulty: ",
|
||||
version = "Version",
|
||||
help_available = _ "An in-game help is available: rightclick on any empty hex.",
|
||||
}
|
||||
|
||||
function wesnoth.wml_actions.wc2_objectives(cfg)
|
||||
wesnoth.wml_actions.objectives {
|
||||
wml.tag.objective {
|
||||
description = strings.wct_victory_condition,
|
||||
condition = "win",
|
||||
},
|
||||
wml.tag.objective {
|
||||
description = strings.turns,
|
||||
condition = "lose",
|
||||
},
|
||||
wml.tag.objective {
|
||||
description = strings.wct_defeat_condition,
|
||||
condition = "lose",
|
||||
},
|
||||
wml.tag.note {
|
||||
description = strings.difficulty .. wml.variables["wc2_difficulty.name"],
|
||||
},
|
||||
wml.tag.note {
|
||||
description = strings.version .. wml.variables["wc2_host_version"],
|
||||
},
|
||||
note = wc2_color.help_text(strings.help_available)
|
||||
}
|
||||
end
|
103
data/campaigns/World_Conquest/lua/campaign/scenario.lua
Normal file
|
@ -0,0 +1,103 @@
|
|||
--<<
|
||||
local wc2_scenario = {}
|
||||
local on_event = wesnoth.require("on_event")
|
||||
|
||||
function wc2_scenario.is_human_side(side_num)
|
||||
return side_num == 1 or side_num == 2 or side_num == 3
|
||||
end
|
||||
|
||||
function wc2_scenario.scenario_num()
|
||||
return wml.variables["wc2_scenario"] or 1
|
||||
end
|
||||
|
||||
function wc2_scenario.experience_penalty()
|
||||
return wml.tag.effect {
|
||||
apply_to = "max_experience",
|
||||
increase = wml.variables["wc2_difficulty.experience_penalty"] .. "%",
|
||||
}
|
||||
end
|
||||
|
||||
-- happens before training events.
|
||||
on_event("recruit", 1, function(ec)
|
||||
local u = wesnoth.get_unit(ec.x1, ec.y1)
|
||||
if (not u) or (not wc2_scenario.is_human_side(u.side)) then
|
||||
return
|
||||
end
|
||||
u:add_modification("advancement", { wc2_scenario.experience_penalty() })
|
||||
end)
|
||||
|
||||
function wesnoth.wml_actions.wc2_start_units(cfg)
|
||||
local u = wesnoth.get_units({ side = cfg.side, canrecruit = true })[1]
|
||||
if not u then error("[wc2_start_units] no leader found") end
|
||||
u:add_modification("advancement", { wc2_scenario.experience_penalty() })
|
||||
u:add_modification("trait", wc2_heroes.trait_heroic )
|
||||
u.hitpoints = u.max_hitpoints
|
||||
u.moves = u.max_moves
|
||||
for i = 1, wml.variables["wc2_difficulty.heroes"] do
|
||||
wesnoth.wml_actions.wc2_random_hero {
|
||||
x = u.x,
|
||||
y = u.y,
|
||||
side = u.side,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function wesnoth.wml_actions.wc2_store_carryover(cfg)
|
||||
local human_sides = wesnoth.get_sides(wml.get_child(cfg, "sides"))
|
||||
--use an the average amount of villages for this scenario to stay independent of map generator results.
|
||||
local nvillages = cfg.nvillages
|
||||
local turns_left = math.max(wesnoth.game_config.last_turn - wesnoth.current.turn, 0)
|
||||
local player_gold = 0
|
||||
|
||||
for side_num, side in ipairs(human_sides) do
|
||||
player_gold = player_gold + side.gold
|
||||
end
|
||||
local player_gold = math.max(player_gold / #human_sides, 0)
|
||||
wml.variables.wc2_carryover = math.ceil( (nvillages*turns_left + player_gold) * 0.15)
|
||||
end
|
||||
|
||||
-- carryover handling: we use a custom carryover machnics that
|
||||
-- splits the carryover gold evenly to all players
|
||||
on_event("prestart", function(cx)
|
||||
wesnoth.fire_event("wc2_start")
|
||||
end)
|
||||
|
||||
-- we need to do this also after difficulöty selection.
|
||||
-- NOTE: this is a bit fragile, in particualr it breaks if difficulty_selection happens before the prestart event above.
|
||||
on_event("wc2_start", function(cx)
|
||||
local gold = (wml.variables.wc2_carryover or 0) + (wml.variables["wc2_difficulty.extra_gold"] or 0)
|
||||
for i = 1, wml.variables.wc2_player_count do
|
||||
wesnoth.sides[i].gold = wesnoth.sides[i].gold + gold
|
||||
end
|
||||
wml.variables.wc2_carryover = nil
|
||||
end)
|
||||
|
||||
-- our victory condition
|
||||
on_event("enemies defeated", function(cx)
|
||||
if wml.variables.wc2_scenario > 5 then
|
||||
return
|
||||
end
|
||||
wesnoth.play_sound("ambient/ship.ogg")
|
||||
wesnoth.wml_actions.endlevel {
|
||||
result = "victory",
|
||||
carryover_percentage = 0,
|
||||
carryover_add = false,
|
||||
carryover_report = false,
|
||||
}
|
||||
end)
|
||||
|
||||
on_event("victory", function(cx)
|
||||
if wml.variables.wc2_scenario > 5 then
|
||||
return
|
||||
end
|
||||
wesnoth.wml_actions.wc2_set_recall_cost { }
|
||||
--{CLEAR_VARIABLE bonus.theme,bonus.point,items}
|
||||
wml.variables.wc2_scenario = (wml.variables.wc2_scenario or 1) + 1
|
||||
end)
|
||||
|
||||
on_event("start", function(cx)
|
||||
wesnoth.wml_actions.wc2_objectives({})
|
||||
end)
|
||||
|
||||
return wc2_scenario
|
||||
-->>
|
29
data/campaigns/World_Conquest/lua/campaign_main.lua
Normal file
|
@ -0,0 +1,29 @@
|
|||
-- the main file for the WC2 mp campaign
|
||||
|
||||
T = wml.tag
|
||||
on_event = wesnoth.require("on_event")
|
||||
|
||||
|
||||
wesnoth.dofile("./game_mechanics/_load.lua")
|
||||
|
||||
wc2_era = wesnoth.require("./era/era.lua")
|
||||
|
||||
wc2_enemy = wesnoth.dofile("./campaign/enemy.lua")
|
||||
|
||||
wc2_scenario = wesnoth.dofile("./campaign/scenario.lua")
|
||||
wesnoth.dofile("./campaign/autorecall.lua")
|
||||
wesnoth.dofile("./campaign/objectives.lua")
|
||||
wesnoth.dofile("./campaign/enemy_themed.lua")
|
||||
|
||||
wc2_difficulty = wesnoth.require("./campaign/difficulty.lua")
|
||||
|
||||
on_event("prestart", function(cx)
|
||||
wesnoth.wml_actions.wc2_fix_colors {
|
||||
wml.tag.player_sides {
|
||||
side="1,2,3",
|
||||
wml.tag.has_unit {
|
||||
canrecruit = true,
|
||||
}
|
||||
}
|
||||
}
|
||||
end)
|
371
data/campaigns/World_Conquest/lua/era/era.lua
Normal file
|
@ -0,0 +1,371 @@
|
|||
local helper = wesnoth.require("helper")
|
||||
local on_event = wesnoth.require("on_event")
|
||||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
|
||||
local wc2_era = {}
|
||||
wc2_era.factions_wml = {}
|
||||
wc2_era.standard_factions = {}
|
||||
wc2_era.hero_types = {}
|
||||
wc2_era.hero_traits = {}
|
||||
wc2_era.spawn_filters = {}
|
||||
|
||||
local strings = {
|
||||
info_menu = _"Tell me how my recruit works",
|
||||
info_recruit = _"Every time you recruit a unit, it is replaced in your recruit list by its pair. The following pairs can also be found here:",
|
||||
}
|
||||
|
||||
local images = {
|
||||
menu_recruit_info = "icons/action/editor-tool-unit_25.png~CROP(3,4,18,18)~GS()"
|
||||
}
|
||||
|
||||
-- the wc2 recruit pair logic.
|
||||
on_event("recruit", function(ctx)
|
||||
local unit = wesnoth.get_unit(ctx.x1, ctx.y1)
|
||||
|
||||
local side_num = unit.side
|
||||
local side = wesnoth.sides[side_num]
|
||||
local unittype = unit.type
|
||||
|
||||
for i,v in ipairs(wml.array_access.get("wc2.pair", side)) do
|
||||
local p = wc2_utils.split_to_array(v.types)
|
||||
if p[1] == unittype and p[2] ~= nil then
|
||||
wesnoth.wml_actions.disallow_recruit {
|
||||
side = side_num,
|
||||
type = p[1],
|
||||
}
|
||||
wesnoth.wml_actions.allow_recruit {
|
||||
side = side_num,
|
||||
type = p[2],
|
||||
}
|
||||
p[1],p[2] = p[2],p[1]
|
||||
side.variables["wc2.pair[" .. (i - 1) .. "].types"] = table.concat(p, ",")
|
||||
wesnoth.allow_undo(false)
|
||||
return
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function wc2_era.get_faction(id)
|
||||
if type(id) == "number" then
|
||||
local side = wesnoth.sides[id]
|
||||
id = side.variables["wc2.faction_id"] or side.faction
|
||||
end
|
||||
for i, faction in ipairs(wc2_era.factions_wml) do
|
||||
if faction.id == id then
|
||||
return faction
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function init_side(side_num)
|
||||
|
||||
if wesnoth.get_side_variable(side_num, "wc2.faction_id") ~= nil then
|
||||
-- don't do this twice.
|
||||
return
|
||||
end
|
||||
local side = wesnoth.sides[side_num]
|
||||
local faction = wc2_era.get_faction(side_num)
|
||||
|
||||
if faction and side.variables["wc2.pair.length"] == 0 and wml.get_child(faction, "pair") then
|
||||
side.variables["wc2.faction_id"] = faction.id
|
||||
wesnoth.wml_actions.disallow_recruit { side = side_num, recruit="" }
|
||||
local i = 0
|
||||
for v in wml.child_range(faction, "pair") do
|
||||
i = i + 1
|
||||
local p = wc2_utils.split_to_array(v.types)
|
||||
if wesnoth.random(1,2) == 2 then
|
||||
p[1],p[2] = p[2],p[1]
|
||||
end
|
||||
wesnoth.wml_actions.allow_recruit {
|
||||
side = side_num,
|
||||
type = p[1],
|
||||
}
|
||||
side.variables["wc2.pair[" .. (i - 1) .. "].types"] = table.concat(p, ",")
|
||||
end
|
||||
end
|
||||
|
||||
if not faction and #wc2_era.factions_wml > 0 then
|
||||
faction = wc2_era.factions_wml[wesnoth.random(#wc2_era.factions_wml)]
|
||||
end
|
||||
|
||||
if not faction then
|
||||
faction = wc2_era.create_random_faction()
|
||||
end
|
||||
|
||||
local heroes = wc2_era.expand_hero_types(faction.heroes)
|
||||
local deserters = wc2_era.expand_hero_types(faction.deserters)
|
||||
local commanders = wc2_era.expand_hero_types(faction.commanders)
|
||||
|
||||
helper.shuffle(heroes)
|
||||
helper.shuffle(deserters)
|
||||
helper.shuffle(commanders)
|
||||
|
||||
side.variables["wc2.heroes"] = table.concat(heroes, ",")
|
||||
side.variables["wc2.deserters"] = table.concat(deserters, ",")
|
||||
side.variables["wc2.commanders"] = table.concat(commanders, ",")
|
||||
end
|
||||
|
||||
local function add_known_faction(cfg)
|
||||
table.insert(wc2_era.factions_wml, cfg)
|
||||
end
|
||||
|
||||
local function add_known_hero_group(id, cfg)
|
||||
wc2_era.hero_types[id] = cfg
|
||||
end
|
||||
|
||||
local function add_known_spawn_filter(spawn_filter)
|
||||
local types = wc2_utils.split_to_set(spawn_filter.types)
|
||||
local filter_location = wml.get_child(spawn_filter, "filter_location") or helper.wml_error("missing [filter_location] in [hero_spawn_filter]")
|
||||
table.insert(wc2_era.spawn_filters, { types = types, filter_location = filter_location} )
|
||||
end
|
||||
|
||||
local function add_known_trait_extra(trait_extra)
|
||||
local types = wc2_utils.split_to_set(trait_extra.types)
|
||||
local trait = wml.get_child(trait_extra, "trait") or helper.wml_error("missing [trait] in [trait_extra]")
|
||||
table.insert(wc2_era.hero_traits, { types = types, trait = trait} )
|
||||
end
|
||||
-- in case that a [multiplayer_side] has not [world_conquest_data] we generate it randomly.
|
||||
function wc2_era.create_random_faction(id)
|
||||
|
||||
local deserters_set = {}
|
||||
local heros_set = {}
|
||||
local commanders_set = {}
|
||||
|
||||
local i_deserters1 = wesnoth.random(#wc2_era.standard_factions)
|
||||
local i_deserters2 = wesnoth.random(#wc2_era.standard_factions)
|
||||
local i_heroes1 = wesnoth.random(#wc2_era.standard_factions)
|
||||
local i_heroes2 = wesnoth.random(#wc2_era.standard_factions)
|
||||
local i_commanders = wesnoth.random(#wc2_era.standard_factions)
|
||||
|
||||
wc2_utils.split_to_set(wc2_era.standard_factions[i_deserters1].recruits, deserters_set)
|
||||
wc2_utils.split_to_set(wc2_era.standard_factions[i_deserters2].recruits, deserters_set)
|
||||
wc2_utils.split_to_set(wc2_era.standard_factions[i_heroes1].recruits, heros_set)
|
||||
wc2_utils.split_to_set(wc2_era.standard_factions[i_heroes2].recruits, heros_set)
|
||||
wc2_utils.split_to_set(wc2_era.standard_factions[i_commanders].recruits, commanders_set)
|
||||
|
||||
local faction = {
|
||||
id = "custom_random",
|
||||
deserters = table.concat( wc2_utils.set_to_array(deserters_set), ","),
|
||||
heroes = table.concat( wc2_utils.set_to_array(heros_set), ","),
|
||||
commanders = table.concat( wc2_utils.set_to_array(commanders_set), ","),
|
||||
}
|
||||
return faction
|
||||
end
|
||||
|
||||
function wc2_era.read_era_tag(era_wml)
|
||||
era_wml = wml.literal(era_wml)
|
||||
|
||||
for multiplayer_side in wml.child_range(era_wml, "multiplayer_side") do
|
||||
if not multiplayer_side.random_faction then
|
||||
--used for random faction generation.
|
||||
table.insert(wc2_era.standard_factions, {
|
||||
id = multiplayer_side.id,
|
||||
recruits = multiplayer_side.recruit
|
||||
})
|
||||
end
|
||||
local faction = wml.get_child(multiplayer_side, "world_conquest_data")
|
||||
if faction then
|
||||
faction.id = multiplayer_side.id
|
||||
faction.name = multiplayer_side.name
|
||||
faction.image = multiplayer_side.image
|
||||
add_known_faction(faction)
|
||||
end
|
||||
end
|
||||
-- No need to read [hero_types] since wc2_utils.get_wc2_data also reads from [era]
|
||||
end
|
||||
|
||||
function wc2_era.init_era_default()
|
||||
wc2_era.read_era_tag(wesnoth.game_config.era)
|
||||
wc2_era.init_data()
|
||||
end
|
||||
|
||||
function wc2_era.init_data()
|
||||
|
||||
for i,v in ipairs(wml.get_child(wc2_utils.get_wc2_data("hero_types"), "hero_types")) do
|
||||
add_known_hero_group(v[1], v[2])
|
||||
end
|
||||
|
||||
for trait_extra in wml.child_range(wc2_utils.get_wc2_data("trait_extra"), "trait_extra") do
|
||||
add_known_trait_extra(trait_extra)
|
||||
end
|
||||
|
||||
for spawn_filter in wml.child_range(wc2_utils.get_wc2_data("hero_spawn_filter"), "hero_spawn_filter") do
|
||||
add_known_spawn_filter(spawn_filter)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function wesnoth.wml_actions.wc2_init_era(cfg)
|
||||
cfg = wml.literal(cfg)
|
||||
|
||||
if cfg.clear then
|
||||
wc2_era.factions_wml = {}
|
||||
wc2_era.hero_types = {}
|
||||
wc2_era.hero_traits = {}
|
||||
wc2_era.spawn_filters = {}
|
||||
end
|
||||
|
||||
wc2_era.wc2_era_id = cfg.wc2_era_id -- TODO removed for testing or error("missing wc2_era_id")
|
||||
for faction in wml.child_range(cfg, "faction") do
|
||||
add_known_faction(faction)
|
||||
end
|
||||
|
||||
for i,v in ipairs(wml.get_child(cfg, "hero_types")) do
|
||||
add_known_hero_group(v[1], v[2])
|
||||
end
|
||||
|
||||
for trait_extra in wml.child_range(cfg, "trait_extra") do
|
||||
add_known_trait_extra(trait_extra)
|
||||
end
|
||||
|
||||
for spawn_filter in wml.child_range(cfg, "hero_spawn_filter") do
|
||||
add_known_spawn_filter(spawn_filter)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- picks a deserter for the side @a side_num using the list of posibel deserters for that sides faction.
|
||||
function wc2_era.pick_deserter(side_num)
|
||||
local side_variables = wesnoth.sides[side_num].variables
|
||||
local deserters = wc2_utils.split_to_array(side_variables["wc2.deserters"])
|
||||
if #deserters == 0 then
|
||||
return nil
|
||||
end
|
||||
-- fixme: shouldn't we randomoize this?
|
||||
local index = #deserters
|
||||
local res = deserters[index]
|
||||
table.remove(deserters, index)
|
||||
side_variables["wc2.deserters"] = table.concat(deserters, ",")
|
||||
return res
|
||||
end
|
||||
|
||||
-- replaces group ids with the corresponding unit lists.
|
||||
-- @a types_str a comma seperated list of unti types and group ids.
|
||||
-- @returns an array of unit types.
|
||||
function wc2_era.expand_hero_types(types_str)
|
||||
local types = wc2_utils.split_to_array(types_str)
|
||||
local types_new = {}
|
||||
local types_res = {}
|
||||
while #types > 0 do
|
||||
for i,v in ipairs(types) do
|
||||
if wesnoth.unit_types[v] then
|
||||
table.insert(types_res, v)
|
||||
elseif wc2_era.hero_types[v] then
|
||||
local group = wc2_era.hero_types[v]
|
||||
wc2_utils.split_to_array(group.types, types_new)
|
||||
else
|
||||
wesnoth.message("WCII ERROR", "unknown deserter group: '" .. v .. "'")
|
||||
end
|
||||
end
|
||||
types = types_new
|
||||
types_new = {}
|
||||
end
|
||||
wc2_utils.remove_dublicates(types_res)
|
||||
return types_res
|
||||
end
|
||||
|
||||
-- replaces group ids with the corresponding unit lists.and replaces unit type ids with their names. (used by wocopedia)
|
||||
-- @a types_str a comma seperated list of unti types and group ids.
|
||||
-- @returns an array of unit type names.
|
||||
function wc2_era.expand_hero_names(types_str, only_unitnames)
|
||||
local types = wc2_utils.split_to_array(types_str)
|
||||
local types_new = {}
|
||||
local names_res = {}
|
||||
while #types > 0 do
|
||||
for i,v in ipairs(types) do
|
||||
local ut = wesnoth.unit_types[v]
|
||||
if ut then
|
||||
table.insert(names_res, ut.name)
|
||||
else
|
||||
local group = wc2_era.hero_types[v]
|
||||
if group.name and not only_unitnames then
|
||||
table.insert(names_res, group.name)
|
||||
else
|
||||
wc2_utils.split_to_array(group.types, types_new)
|
||||
end
|
||||
end
|
||||
end
|
||||
types = types_new
|
||||
types_new = {}
|
||||
end
|
||||
return names_res
|
||||
end
|
||||
|
||||
on_event("prestart", function()
|
||||
for i, s in ipairs(wesnoth.sides) do
|
||||
init_side(i)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Generates the list of possible unit types that can be found in bonus points.
|
||||
function wc2_era.generate_bonus_heroes()
|
||||
return wc2_era.expand_hero_types("Bonus_All")
|
||||
end
|
||||
|
||||
-- shows the recruit info dialog for the faction of the currently viewing side.
|
||||
function wesnoth.wml_actions.wc2_recruit_info(cfg)
|
||||
|
||||
local side_num = wesnoth.get_viewing_side()
|
||||
local faction = wc2_era.get_faction(side_num)
|
||||
if not faction then
|
||||
wesnoth.wml_actions.message {
|
||||
scroll = false,
|
||||
canrecruit = true,
|
||||
side = side_num,
|
||||
message = _ "You are not using a WC2 faction.",
|
||||
}
|
||||
return
|
||||
end
|
||||
local message = {
|
||||
scroll = false,
|
||||
canrecruit = true,
|
||||
side = side_num,
|
||||
caption = faction.name,
|
||||
message = cfg.message,
|
||||
}
|
||||
|
||||
for i,v in ipairs(wml.array_access.get("wc2.pair", side_num)) do
|
||||
local p = wc2_utils.split_to_array(v.types)
|
||||
local ut1 = wesnoth.unit_types[p[1]]
|
||||
local ut2 = wesnoth.unit_types[p[2]]
|
||||
local img = "misc/blank.png~SCALE(144,72)" ..
|
||||
"~BLIT(" .. wc2_color.tc_image(side_num, ut1.image) .. ")" ..
|
||||
"~BLIT(" .. wc2_color.tc_image(side_num, ut2.image) .. ",72,0)"
|
||||
table.insert(message, {"option", {
|
||||
image = img,
|
||||
label= ut1.name,
|
||||
description = ut2.name,
|
||||
}})
|
||||
end
|
||||
wesnoth.wml_actions.message(message)
|
||||
end
|
||||
|
||||
wc2_utils.menu_item {
|
||||
id="1_WC_II_Era_Info_Recruit_Option",
|
||||
description=strings.info_menu,
|
||||
image=images.menu_recruit_info,
|
||||
synced=false,
|
||||
filter = function (x, y)
|
||||
local u wesnoth.get_unit(x, y)
|
||||
if u and u.side == wesnoth.current.side then
|
||||
return false
|
||||
end
|
||||
if not wc2_era.get_faction(wesnoth.get_viewing_side()) then
|
||||
return false
|
||||
end
|
||||
if wc2_artifacts.is_item_at(x, y) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end,
|
||||
handler = function(cx)
|
||||
wesnoth.wml_actions.wc2_recruit_info {
|
||||
message = strings.info_recruit
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
wc2_era.init_era_default()
|
||||
|
||||
return wc2_era
|
4
data/campaigns/World_Conquest/lua/era_main.lua
Normal file
|
@ -0,0 +1,4 @@
|
|||
-- the main file for the WC2 mp era
|
||||
|
||||
wc2_utils = wesnoth.require('./game_mechanics/utils.lua')
|
||||
wc2_era = wesnoth.require('./era/era.lua')
|
29
data/campaigns/World_Conquest/lua/game_mechanics/_load.lua
Normal file
|
@ -0,0 +1,29 @@
|
|||
|
||||
-- Loads the WC2 'engine' that is making bonus points, items, training etc work.
|
||||
|
||||
wc2_convert = wesnoth.require("./../shared_utils/wml_converter.lua")
|
||||
|
||||
wc2_ability_events = wesnoth.require("./ability_events.lua")
|
||||
wc2_artifacts = wesnoth.require("./artifacts.lua")
|
||||
wc2_bonus = wesnoth.require("./bonus.lua")
|
||||
wc2_color = wesnoth.require("./color.lua")
|
||||
wc2_dropping = wesnoth.require("./dropping.lua")
|
||||
wc2_effects = wesnoth.require("./effects.lua")
|
||||
wc2_heroes = wesnoth.require("./heroes.lua")
|
||||
wc2_pickup_confirmation_dialog = wesnoth.require("./pickup_confirmation_dialog.lua")
|
||||
wc2_random_names = wesnoth.require("./random_names.lua")
|
||||
wc2_recall = wesnoth.require("./recall.lua")
|
||||
wc2_supply = wesnoth.require("./supply.lua")
|
||||
wc2_training = wesnoth.require("./training.lua")
|
||||
wc2_unittypedata = wesnoth.require("./unittypedata.lua")
|
||||
wc2_utils = wesnoth.require("./utils.lua")
|
||||
|
||||
wc2_wiki_dialog = wesnoth.require("./wocopedia/help_dialog.lua")
|
||||
wc2_wiki = wesnoth.require("./wocopedia/help.lua")
|
||||
|
||||
wc2_invest = wesnoth.require("./invest/invest.lua")
|
||||
wc2_invest_dialog = wesnoth.require("./invest/invest_dialog.lua")
|
||||
wc2_invest_show_dialog = wesnoth.require("./invest/invest_show_dialog.lua")
|
||||
wc2_invest_tellunit = wesnoth.require("./invest/invest_tellunit.lua")
|
||||
|
||||
wesnoth.require("./promote_commander.lua")
|
|
@ -0,0 +1,52 @@
|
|||
local on_event = wesnoth.require("on_event")
|
||||
|
||||
----- the 'full movement on turn recuited' ability implementation -----
|
||||
-- priority -1 because this event must be happen after the training event.
|
||||
on_event("recruit,recall", -1, function(ec)
|
||||
local unit = wesnoth.get_unit(ec.x1, ec.y1)
|
||||
if not unit then
|
||||
return
|
||||
end
|
||||
local matches = unit.variables["mods.wc2_move_on_recruit"]
|
||||
|
||||
if matches then
|
||||
unit.attacks_left = 1
|
||||
unit.moves = unit.max_moves
|
||||
end
|
||||
end)
|
||||
|
||||
----- the 'corruption' ability implementation -----
|
||||
on_event("turn_refresh", function(event_context)
|
||||
wesnoth.wml_actions.harm_unit {
|
||||
wml.tag.filter {
|
||||
wml.tag.filter_side {
|
||||
wml.tag.enemy_of {
|
||||
side = wesnoth.current.side,
|
||||
},
|
||||
},
|
||||
wml.tag.filter_adjacent {
|
||||
side = wesnoth.current.side,
|
||||
ability = "wc2_corruption",
|
||||
},
|
||||
},
|
||||
amount = 6,
|
||||
kill = false,
|
||||
animate = true,
|
||||
}
|
||||
end)
|
||||
|
||||
----- the 'disengage' ability implementation -----
|
||||
on_event("attack_end", function(cx)
|
||||
local u = wesnoth.get_unit(cx.x1, cx.y1)
|
||||
if not u then
|
||||
return
|
||||
end
|
||||
if not u:matches { wml.tag.has_attack { special_active = "wc2_disengage"} } then
|
||||
--IMPORTANT: using 'special_active' like this is only guaranteed to work if
|
||||
-- the attack has a [filter_self] or a simlar filter tag, otherwise it might
|
||||
-- also fire when another attack that is not the currently used attack has
|
||||
-- that special
|
||||
return
|
||||
end
|
||||
u.moves = 1
|
||||
end)
|
247
data/campaigns/World_Conquest/lua/game_mechanics/artifacts.lua
Normal file
|
@ -0,0 +1,247 @@
|
|||
local on_event = wesnoth.require("on_event")
|
||||
local helper = wesnoth.require("helper")
|
||||
|
||||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
|
||||
local artifacts = {}
|
||||
artifacts.list = {}
|
||||
|
||||
function artifacts.add_artifact_data(a)
|
||||
table.insert(artifacts.list, a)
|
||||
end
|
||||
|
||||
function artifacts.read_wml_data(cfg)
|
||||
for i, artifact in ipairs(wc2_convert.wml_to_lon(wml.literal(cfg), "wct_artifact_list").artifact or {}) do
|
||||
artifacts.add_artifact_data(artifact)
|
||||
end
|
||||
end
|
||||
|
||||
function artifacts.init_data()
|
||||
local cfg = wc2_utils.get_wc2_data("artifact")
|
||||
for i, a in ipairs(wc2_convert.wml_to_lon(cfg, "wct_artifact_list").artifact or {}) do
|
||||
artifacts.add_artifact_data(a)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function artifacts.get_artifact(id)
|
||||
return artifacts.list[id]
|
||||
end
|
||||
|
||||
function artifacts.get_artifact_list()
|
||||
return artifacts.list
|
||||
end
|
||||
|
||||
|
||||
function artifacts.drop_message(index)
|
||||
local aftifact_data = artifacts.get_artifact(index)
|
||||
wesnoth.wml_actions.message {
|
||||
speaker = "narrator",
|
||||
caption = aftifact_data.name,
|
||||
message = aftifact_data.info .. "\n" .. wc2_color.bonus_text(aftifact_data.description),
|
||||
image = aftifact_data.icon,
|
||||
}
|
||||
end
|
||||
|
||||
function wc2_artifact_needs_compensation(side)
|
||||
return not wc2_scenario.is_human_side(side.side)
|
||||
end
|
||||
|
||||
|
||||
-- place an artifact with id @a index on the map at position @a x, y.
|
||||
-- can be used from the bug console as `lua wc2_artifacts.place_item(30,20,1)`
|
||||
function artifacts.place_item(x, y, index)
|
||||
wc2_dropping.add_item(x, y, {
|
||||
wc2_atrifact_id = index,
|
||||
image = artifacts.get_artifact(index).icon,
|
||||
z_order = 20,
|
||||
})
|
||||
end
|
||||
|
||||
-- give te item with id @a index to unit @a unit, set @a visualize=true, to show the item pickup animation.
|
||||
function artifacts.give_item(unit, index, visualize)
|
||||
local aftifact_data = artifacts.get_artifact(index)
|
||||
if visualize then
|
||||
-- play visual/sound effects if item have any
|
||||
wesnoth.wml_actions.sound {
|
||||
name = aftifact_data.sound or ""
|
||||
}
|
||||
if unit.gender == "male" then
|
||||
wesnoth.wml_actions.sound {
|
||||
name = aftifact_data.sound_male or ""
|
||||
}
|
||||
else
|
||||
wesnoth.wml_actions.sound {
|
||||
name = aftifact_data.sound_female or ""
|
||||
}
|
||||
end
|
||||
for i, animate_unit in ipairs(aftifact_data.animate_unit) do
|
||||
wesnoth.wml_actions.animate_unit(animate_unit)
|
||||
end
|
||||
end
|
||||
local make_holder_loyal = wml.variables["wc2_config_items_make_loyal"] ~= false
|
||||
-- is_commander or is_hero imples unit.upkeep == "loyal"
|
||||
-- note that the following `unit.upkeep` does not match normal
|
||||
-- level 0 (which have still 'full' upkeep) only units with upkeep=0 explicitly set
|
||||
if make_holder_loyal and (not unit.canrecruit) and (unit.upkeep ~= 0) and (unit.upkeep ~= "loyal") then
|
||||
unit:add_modification("object", { wml.tag.effect { apply_to = "wc2_overlay", add = "misc/loyal-icon.png" }})
|
||||
end
|
||||
|
||||
local object = {
|
||||
wc2_atrifact_id = index,
|
||||
-- cannot filter on wc2_atrifact_id beeing empty so we also need wc2_is_artifact
|
||||
wc2_is_artifact = true,
|
||||
}
|
||||
if make_holder_loyal then
|
||||
table.insert(object, wml.tag.effect { apply_to= "loyal" })
|
||||
end
|
||||
|
||||
|
||||
-- IDEA: i _could_ replace the follwing with a 'apply_to=wc2_artifact' effect that
|
||||
-- basicially applies all effects in the [artifact]s definition. The obvious
|
||||
-- advantage would be a smaller savefile size. Also this woudl change how savefiles
|
||||
-- would behve if an artifacts effect has changed, i am currently not sure
|
||||
-- whether that'd be good or bad
|
||||
--
|
||||
-- One of the reasons why i currently won't do this is to make the artifacts list
|
||||
-- more flixible: the suggested approach requires that artifacts are loaded before
|
||||
-- units are created which means artifacts must be loaded at toplevel [lua] tags
|
||||
for i, effect in ipairs(aftifact_data.effect) do
|
||||
table.insert(object, wml.tag.effect (effect) )
|
||||
end
|
||||
unit:add_modification("object", object)
|
||||
--rebuild unit, to reduce savefile size.
|
||||
unit:transform(unit.type)
|
||||
-- the artifact might reduce the max xp.
|
||||
unit:advance(true, true)
|
||||
end
|
||||
|
||||
-- unit picking up artifacts
|
||||
on_event("wc2_drop_pickup", function(ec)
|
||||
local item = wc2_dropping.current_item
|
||||
local unit = wesnoth.get_unit(ec.x1, ec.y1)
|
||||
if not item.wc2_atrifact_id then
|
||||
return
|
||||
end
|
||||
|
||||
if not unit then
|
||||
return
|
||||
end
|
||||
|
||||
local side_num = unit.side
|
||||
local is_human = wc2_scenario.is_human_side(side_num)
|
||||
if not wml.variables["wc2_config_experimental_pickup"] and not is_human then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local index = item.wc2_atrifact_id
|
||||
local filter = artifacts.get_artifact(index).filter
|
||||
if filter and not unit:matches(filter) then
|
||||
if is_human then
|
||||
wesnoth.wml_actions.message {
|
||||
id = unit.id,
|
||||
message = _"I cannot pick up that item.",
|
||||
}
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if is_human and not wml.variables["wc2_config_disable_pickup_confirm"] then
|
||||
if not wc2_pickup_confirmation_dialog.promt_synced(unit, artifacts.get_artifact(index).icon) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
wc2_dropping.item_taken = true
|
||||
artifacts.give_item(unit, index, true)
|
||||
wesnoth.allow_undo(false)
|
||||
end)
|
||||
|
||||
-- returns a list of artifact ids, suitable for the give type ('enemy' for example).
|
||||
function artifacts.fresh_artifacts_list(for_type)
|
||||
local res = {}
|
||||
for i,v in ipairs(artifacts.get_artifact_list()) do
|
||||
if not for_type or not wc2_utils.split_to_set(v.not_available or "")[for_type] then
|
||||
table.insert(res, i)
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
|
||||
-- drop all items a dying unit carries.
|
||||
on_event("die", function(event_context)
|
||||
local unit = wesnoth.get_unit(event_context.x1, event_context.y1)
|
||||
if not unit then
|
||||
return
|
||||
end
|
||||
if not wml.variables["wc2_config_experimental_pickup"] and wc2_scenario.is_human_side(unit.side) then
|
||||
return
|
||||
end
|
||||
for object in helper.child_range(wml.get_child(unit.__cfg, "modifications") or {}, "object") do
|
||||
if object.wc2_atrifact_id then
|
||||
artifacts.place_item(unit.x, unit.y, object.wc2_atrifact_id)
|
||||
artifacts.drop_message(object.wc2_atrifact_id)
|
||||
wesnoth.allow_undo(false)
|
||||
end
|
||||
end
|
||||
|
||||
-- remove the item from the unit, just in case the unit is somehow brought back to life by another addons code. (for example 'besieged druid' can do such a thing)
|
||||
unit:remove_modifications { wc2_is_artifact = true }
|
||||
end)
|
||||
|
||||
-- returns true if there is an item in the map at the given position,
|
||||
-- used to determine whether to show the artifact info menu at that position.
|
||||
function artifacts.is_item_at(x,y)
|
||||
for i,item in ipairs(wc2_dropping.get_entries_at_readonly(x,y)) do
|
||||
if item.wc2_atrifact_id then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- shows an information [message] about the item laying at position
|
||||
-- @a cfg.x, cfg.y
|
||||
function wesnoth.wml_actions.wc2_show_item_info(cfg)
|
||||
local x = cfg.x
|
||||
local y = cfg.y
|
||||
for i,item in ipairs(wc2_dropping.get_entries_at_readonly(x,y)) do
|
||||
if item.wc2_atrifact_id then
|
||||
local artifact_info = artifacts.get_artifact(item.wc2_atrifact_id)
|
||||
wesnoth.wml_actions.message {
|
||||
scroll = false,
|
||||
image = artifact_info.icon,
|
||||
caption = artifact_info.name,
|
||||
message= artifact_info.info .. "\n" .. wc2_color.help_text(artifact_info.description),
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wc2_utils.menu_item {
|
||||
id="4_WCT_Item_Info_Option",
|
||||
description = _ "Remind me what this item does",
|
||||
image = "icons/terrain/terrain_type_info.png",
|
||||
synced = false,
|
||||
filter = artifacts.is_item_at,
|
||||
handler = function(cx)
|
||||
wesnoth.wml_actions.wc2_show_item_info {
|
||||
x = cx.x1,
|
||||
y = cx.y1,
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
function wesnoth.wml_actions.wc2_place_item(cfg)
|
||||
artifacts.place_item(cfg.x, cfg.y, cfg.item_index)
|
||||
if cfg.message then
|
||||
artifacts.drop_message(cfg.item_index)
|
||||
end
|
||||
end
|
||||
|
||||
artifacts.init_data()
|
||||
|
||||
return artifacts
|
231
data/campaigns/World_Conquest/lua/game_mechanics/bonus.lua
Normal file
|
@ -0,0 +1,231 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local on_event = wesnoth.require("on_event")
|
||||
local helper = wesnoth.require("helper")
|
||||
|
||||
local bonus = {}
|
||||
bonus.sceneries = {}
|
||||
|
||||
-- places a bonus point on the map.
|
||||
function wesnoth.wml_actions.wc2_place_bonus(cfg)
|
||||
local x = cfg.x or helper.wml_error("[wc2_place_bonus] missing required 'x' attribute")
|
||||
local y = cfg.y or helper.wml_error("[wc2_place_bonus] missing required 'y' attribute")
|
||||
local scenery = cfg.scenery or helper.wml_error("[wc2_place_bonus] missing required 'scenery' attribute")
|
||||
local c_scenery = bonus.sceneries[scenery]
|
||||
if not c_scenery then
|
||||
helper.wml_error("[wc2_place_bonus] invalid 'scenery' attribute: ".. tostring(scenery))
|
||||
end
|
||||
local image = c_scenery.image or scenery
|
||||
bonus.place_item(x, y, image)
|
||||
|
||||
-- Note: although the numbrs of options passed to helper.rand might depend on the langauge
|
||||
-- the number of thimes random is called does not (random is called even if there is
|
||||
-- only one option), so this doesn't cause OOS.
|
||||
local name1 = wc2_random_names.generate()
|
||||
local name_options = c_scenery.names or { _"place" }
|
||||
local name2 = tostring(name_options[wesnoth.random(#name_options)])
|
||||
|
||||
local function span_font_family(str, fam)
|
||||
return string.format("<span font-family='%s'>%s</span>", fam, str)
|
||||
end
|
||||
print("placed label", x, y)
|
||||
wesnoth.wml_actions.label {
|
||||
x = x,
|
||||
y = y,
|
||||
text = span_font_family(wesnoth.format(_ "$name's $type", {name = name1, type = name2}), "Lucida Sans Unicode")
|
||||
}
|
||||
end
|
||||
|
||||
function bonus.place_item(x, y, image)
|
||||
if image == "campfire" then
|
||||
wesnoth.set_terrain(x, y, "*^Ecf", "overlay")
|
||||
image = nil
|
||||
else
|
||||
image = image or "scenery/lighthouse.png"
|
||||
end
|
||||
|
||||
wc2_dropping.add_item(x, y, {
|
||||
wc2_is_bonus = true,
|
||||
image = image,
|
||||
z_order = 10,
|
||||
})
|
||||
end
|
||||
|
||||
function bonus.remove_current_item(ec)
|
||||
wc2_dropping.remove_current_item()
|
||||
--TODO: i don't think its worth to keep this code, to alos allow bonus points to use terrains instead of overlays.
|
||||
wesnoth.wml_actions.terrain {
|
||||
x = ec.x1,
|
||||
y = ec.y1,
|
||||
wml.tag["and"] {
|
||||
terrain = "*^Ecf",
|
||||
},
|
||||
terrain = "Gs",
|
||||
layer = "overlay",
|
||||
}
|
||||
wesnoth.wml_actions.item {
|
||||
x = ec.x1,
|
||||
y = ec.y1,
|
||||
image = "scenery/rubble.png",
|
||||
z_order = -10,
|
||||
}
|
||||
end
|
||||
|
||||
-- check to be overwritten by other mods.
|
||||
function bonus.can_pickup_bonus(side_num, x, y)
|
||||
return wc2_scenario.is_human_side(side_num)
|
||||
end
|
||||
|
||||
-- callback to be overwritten by other mods.
|
||||
function bonus.post_pickup(side_num, x, y)
|
||||
end
|
||||
|
||||
|
||||
-- event fired by dropping.lua
|
||||
on_event("wc2_drop_pickup", function(ec)
|
||||
local item = wc2_dropping.current_item
|
||||
local side_num = wesnoth.current.side
|
||||
|
||||
if not item.wc2_is_bonus then
|
||||
return
|
||||
end
|
||||
|
||||
if not bonus.can_pickup_bonus(side_num, ec.x1, ec.y1) then
|
||||
return
|
||||
end
|
||||
|
||||
local bonus_type = item.wc2_type
|
||||
if bonus_type == nil then
|
||||
local training_chance = wml.variables.wc2_config_training_chance or 1
|
||||
local hero_chance = wml.variables.wc2_config_hero_chance or 1
|
||||
local item_chance = wml.variables.wc2_config_item_chance or 1
|
||||
local r = wesnoth.random(training_chance + hero_chance + item_chance)
|
||||
if r <= training_chance then
|
||||
bonus_type = 1
|
||||
elseif r <= training_chance + item_chance then
|
||||
bonus_type = 2
|
||||
else
|
||||
bonus_type = 3
|
||||
end
|
||||
end
|
||||
local bonus_subtype = item.wc2_subtype
|
||||
if bonus_type == 1 then
|
||||
if not bonus.found_training(wesnoth.current.side, bonus_subtype, ec) then
|
||||
bonus_type = wesnoth.random(2,3)
|
||||
bonus_subtype = nil
|
||||
end
|
||||
end
|
||||
if bonus_type == 2 then
|
||||
bonus_subtype = bonus_subtype or bonus.get_random_item()
|
||||
bonus.found_artifact(ec, tonumber(bonus_subtype))
|
||||
elseif bonus_type == 3 then
|
||||
bonus_subtype = bonus_subtype or bonus.get_random_hero(ec.x1, ec.y1)
|
||||
bonus.found_hero(ec, bonus_subtype)
|
||||
end
|
||||
bonus.post_pickup(side_num, ec.x1, ec.y1)
|
||||
assert(wc2_dropping.item_taken, "item still there")
|
||||
end)
|
||||
|
||||
function bonus.get_random_item()
|
||||
return tonumber(wc2_utils.pick_random("wc2.random_items", wc2_artifacts.fresh_artifacts_list))
|
||||
end
|
||||
|
||||
function bonus.get_random_hero(x, y)
|
||||
return wc2_utils.pick_random_filtered("wc2.random_heroes", wc2_era.generate_bonus_heroes, function(unittypeid)
|
||||
for _, sf in ipairs(wc2_era.spawn_filters) do
|
||||
if sf.types[unittypeid] and not wesnoth.match_location(x, y, sf.filter_location) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end)
|
||||
end
|
||||
|
||||
function bonus.found_artifact(ec, index)
|
||||
wesnoth.wml_actions.message {
|
||||
x = ec.x1,
|
||||
y = ec.y1,
|
||||
message = _ "Hey, I found some treasure!",
|
||||
}
|
||||
bonus.remove_current_item(ec)
|
||||
wc2_artifacts.drop_message(index)
|
||||
--local x2, y2 = wesnoth.find_vacant_tile(ec.x1, ec.y1)
|
||||
local x2, y2 = ec.x1, ec.y1 + 1
|
||||
wc2_artifacts.place_item(x2, y2, index)
|
||||
return true
|
||||
end
|
||||
|
||||
function bonus.found_hero(ec, herotype)
|
||||
local finder = wesnoth.get_unit(ec.x1, ec.y1)
|
||||
wesnoth.wml_actions.message {
|
||||
x = ec.x1,
|
||||
y = ec.y1,
|
||||
message = _"Someone is here!",
|
||||
}
|
||||
|
||||
bonus.remove_current_item(ec)
|
||||
|
||||
local newunit = wc2_heroes.place(herotype, finder.side, ec.x1, ec.y1)
|
||||
|
||||
-- hero found and unit in bonus point face each other
|
||||
wc2_utils.facing_each_other(finder, newunit)
|
||||
wc2_heroes.founddialouge(finder, newunit)
|
||||
wesnoth.wml_actions.redraw {
|
||||
clear_shroud = true,
|
||||
side = newunit.side,
|
||||
}
|
||||
return true
|
||||
end
|
||||
|
||||
function bonus.found_training(side_num, suggested_subtype, ec)
|
||||
local traintype, amount
|
||||
if suggested_subtype then
|
||||
amount = 1
|
||||
traintype = wc2_training.trainings_left(side_num, suggested_subtype) >= amount and suggested_subtype or nil
|
||||
else
|
||||
traintype, amount = wc2_training.pick_bonus(side_num)
|
||||
end
|
||||
|
||||
if traintype == nil then
|
||||
return false
|
||||
end
|
||||
wesnoth.wml_actions.message {
|
||||
x = ec.x1,
|
||||
y = ec.y1,
|
||||
message = _"Someone is here!",
|
||||
}
|
||||
bonus.remove_current_item(ec)
|
||||
wc2_training.give_bonus(side_num, ec, amount, traintype)
|
||||
return true
|
||||
end
|
||||
|
||||
function bonus.init_data(cfg)
|
||||
local sceneries = bonus.sceneries
|
||||
local lit = wml.literal(cfg)
|
||||
for k,v in pairs(wml.get_child(lit, "str") or {}) do
|
||||
local scenery = sceneries[k] or {}
|
||||
scenery.names = v
|
||||
sceneries[k] = scenery
|
||||
end
|
||||
for k,v in pairs(wml.get_child(lit, "img") or {}) do
|
||||
local scenery = sceneries[k] or {}
|
||||
sceneries[k].image = v
|
||||
sceneries[k] = scenery
|
||||
end
|
||||
end
|
||||
|
||||
if true then
|
||||
local sceneries = bonus.sceneries
|
||||
local strings, images = wesnoth.dofile("./bonus_point_definitions.lua")
|
||||
for k,v in pairs(strings) do
|
||||
local scenery = sceneries[k] or {}
|
||||
scenery.names = v
|
||||
sceneries[k] = scenery
|
||||
end
|
||||
for k,v in pairs(images) do
|
||||
local scenery = sceneries[k] or {}
|
||||
scenery.image = v
|
||||
sceneries[k] = scenery
|
||||
end
|
||||
end
|
||||
|
||||
return bonus
|
|
@ -0,0 +1,325 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
|
||||
local STR_BONUS_SHIP_NAMES = { _"Point", _"Rest", _"Ruin", _"Rocks", _"Bane", _"Waters", _"Route", _"Vestige", _"Disaster", _"Massacre", _"Expedition", _"Cargo" }
|
||||
|
||||
local STR_BONUS_BONES_NAMES = { _"Point", _"Rest", _"Lair", _"Exile", _"Bane", _"Passage", _"Curse" }
|
||||
|
||||
local STR_BONUS_BONES_SWAMP_NAMES = { _"Point", _"Rest", _"Lair", _"Exile", _"Bane", _"Death", _"Passage", _"Curse", _"Quagmire" }
|
||||
|
||||
local STR_BONUS_DEAD_OAK_NAMES = { _"Rest", _"Point", _"Lair", _"Exile", _"Bane", _"Death", _"Curse", _"Wasteland", _"Desolation", _"Despair", _"Desert", _"Route", _"Passage", _"Cementery" }
|
||||
|
||||
local STR_BONUS_VILLAGE_RUINED_NAMES = { _"Rest", _"Ruin", _"Lair", _"Exile", _"Bane", _"Curse", _"Destruction", _"Desolation", _"Vestige", _"Disaster" }
|
||||
|
||||
local STR_BONUS_BURIAL_NAMES = { _"Point", _"Rest", _"Lair", _"Passage", _"Bane", _"Massacre", _"Curse", _"Disaster", _"Cementery" }
|
||||
|
||||
local STR_BONUS_BURIAL_SAND_NAMES = { _"Point", _"Rest", _"Lair", _"Exile", _"Passage", _"Bane", _"Massacre", _"Curse", _"Disaster" }
|
||||
|
||||
local STR_BONUS_BURIAL_CAVE_NAMES = { _"Rest", _"Lair", _"Passage", _"Bane", _"Grotto", _"Curse", _"Cave", _"Cementery", _"Graveyard" }
|
||||
|
||||
local STR_BONUS_DETRITUS_NAMES = { _"Point", _"Rest", _"Ruin", _"Lair", _"Exile", _"Passage", _"Bane", _"Massacre", _"Curse", _"Quagmire", _"Bog", _"Hideout", _"Desolation" }
|
||||
|
||||
local STR_BONUS_TRAPDOOR_NAMES = { _"Rest", _"Ruin", _"Lair", _"Passage", _"Bane", _"Despair", _"Curse", _"Cave", _"Dungeon", _"Secret", _"Hideout", _"Mine", _"Grotto", _"Den" }
|
||||
|
||||
local STR_BONUS_COFFIN_NAMES = { _"Rest", _"Ruin", _"Lair", _"Exile", _"Passage", _"Bane", _"Dream", _"Crypt", _"Grotto", _"Graveyard", _"Secret", _"Curse", _"Mausoleum", _"Ossuary" }
|
||||
|
||||
local STR_BONUS_MINE_NAMES = { _"Lair", _"Passage", _"Bane", _"Peak", _"Mine", _"Curse", _"Den", _"Site", _"Quarry", _"Dungeon" }
|
||||
|
||||
local STR_BONUS_DOORS_NAMES = { _"Rest", _"Lair", _"Passage", _"Bane", _"Peak", _"Mine", _"Destiny", _"Door", _"Gate", _"Curse", _"Domain", _"Secret", _"Dungeon" }
|
||||
|
||||
local STR_BONUS_SHOP_NAMES = { _"Path", _"Road", _"Route", _"Market", _"Fair", _"Festival", _"Tournament", _"Enclave", _"Armory" }
|
||||
|
||||
local STR_BONUS_SHOP_GRASS_NAMES = { _"Route", _"Market", _"Enclave", _"Fair", _"Festival", _"Tournament", _"Armory", _"Refuge" }
|
||||
|
||||
local STR_BONUS_SIGNPOST_NAMES = { _"Rest", _"Path", _"Point", _"Passage", _"Road", _"Route", _"Domain" }
|
||||
|
||||
local STR_BONUS_ROCK_CAIRN_NAMES = { _"Rest", _"Memory", _"Triumph", _"Vestige", _"Point", _"Passage", _"Domain", _"Route", _"Rock" }
|
||||
|
||||
local STR_BONUS_ROCK_CAIRN_CAVE_NAMES = { _"Rest", _"Memory", _"Vestige", _"Grotto", _"Passage", _"Domain", _"Secret", _"Curse", _"Rock" }
|
||||
|
||||
local STR_BONUS_DOLMEN_NAMES = { _"Rest", _"Memory", _"Triumph", _"Vestige", _"Point", _"Passage", _"Domain", _"Route", _"Ruin", _"Road", _"Path" }
|
||||
|
||||
local STR_BONUS_MONOLITH_NAMES = { _"Rest", _"Memory", _"Triumph", _"Vestige", _"Point", _"Path", _"Domain", _"Route", _"Monolith", _"Road" }
|
||||
|
||||
local STR_BONUS_OBELISK_NAMES = { _"Rest", _"Memory", _"Triumph", _"Vestige", _"Point", _"Path", _"Domain", _"Route", _"Obelisk", _"Road" }
|
||||
|
||||
local STR_BONUS_WELL_GRASS_NAMES = { _"Rest", _"Lair", _"Exile", _"Point", _"Passage", _"Ruin", _"Route", _"Refuge", _"Enclave", _"Domain" }
|
||||
|
||||
local STR_BONUS_WELL_ROAD_NAMES = { _"Rest", _"Point", _"Desire", _"Route", _"Passage", _"Refuge", _"Enclave", _"Path", _"Road", _"Market" }
|
||||
|
||||
local STR_BONUS_WELL_CAVE_NAMES = { _"Rest", _"Lair", _"Exile", _"Passage", _"Ruin", _"Well", _"Mine", _"Grotto", _"Den", _"Secret" }
|
||||
|
||||
local STR_BONUS_WELL_CRYSTAL_NAMES = { _"Bane", _"Lair", _"Curse", _"Passage", _"Grotto", _"Cave", _"Mine", _"Site", _"Quarry", _"Secret" }
|
||||
|
||||
local STR_BONUS_MONOLITH_HILLS_NAMES = { _"Rest", _"Point", _"Passage", _"Ruin", _"Lair", _"Exile", _"Plateau", _"Cliff", _"Domain", _"Route", _"Vestige" }
|
||||
|
||||
local STR_BONUS_LIGHTHOUSE_NAMES = { _"Port", _"Seaport", _"Harbor", _"Enclave", _"Bay", _"Coast", _"Shore", _"Lighthouse", _"Domain" }
|
||||
|
||||
local STR_BONUS_CAMPFIRE_NAMES = { _"Port", _"Seaport", _"Harbor", _"Bay", _"Coast", _"Shore", _"Cliff", _"Domain", _"Signal", _"Beacon", _"Enclave" }
|
||||
|
||||
local STR_BONUS_LILIES_NAMES = { _"Point", _"Passage", _"Lair", _"Rest", _"Waters", _"Domain", _"Curse", _"Secret", _"Hideout", _"Bane" }
|
||||
|
||||
local STR_BONUS_LILIES_SWAMP_NAMES = { _"Point", _"Passage", _"Rest", _"Lair", _"Exile", _"Domain", _"Curse", _"Secret", _"Hideout", _"Bane", _"Marsh" }
|
||||
|
||||
local STR_BONUS_ROCK_SAND_NAMES = { _"Rest", _"Point", _"Passage", _"Ruin", _"Lair", _"Exile", _"Delirium", _"Graveyard", _"Cementery", _"Ossuary", _"Domain", _"Route", _"Vestige" }
|
||||
|
||||
local STR_BONUS_ROCK_NAMES = { _"Rest", _"Point", _"Passage", _"Ruin", _"Lair", _"Exile", _"Domain", _"Route", _"Vestige" }
|
||||
|
||||
local STR_BONUS_DOLMEN_GRASS_NAMES = { _"Rest", _"Point", _"Passage", _"Ruin", _"Lair", _"Domain", _"Route", _"Vestige", _"Conclave", _"Graveyard" }
|
||||
|
||||
local STR_BONUS_WINDMILL_NAMES = { _"Meadow", _"Prairie", _"Grassland", _"Refuge", _"Windmill", _"Enclave", _"Domain", _"Farm", _"Granary", _"Field", _"Shire" }
|
||||
|
||||
local STR_BONUS_TENT_NAMES = { _"Exile", _"Route", _"Enclave", _"Domain", _"Outpost", _"Refuge" }
|
||||
|
||||
local STR_BONUS_TENT_FANCY_GRASS_NAMES = { _"Exile", _"Route", _"Enclave", _"Domain", _"Outpost", _"Refuge", _"Festival", _"Fair", _"Tournament" }
|
||||
|
||||
local STR_BONUS_TENT_FANCY_ROAD_NAMES = { _"Route", _"Road", _"Path", _"Enclave", _"Domain", _"Outpost", _"Refuge", _"Festival", _"Fair", _"Tournament", _"Market", _"Armory" }
|
||||
|
||||
local STR_BONUS_SHELTER_NAMES = { _"Passage", _"Exile", _"Route", _"Refuge", _"Domain", _"Shelter", _"Shelter", _"Quarry", _"Plateau", _"Site", _"Outpost", _"Enclave", _"Passage" }
|
||||
|
||||
local STR_BONUS_TENT_OUTPOST_NAMES = { _"Exile", _"Route", _"Refuge", _"Domain", _"Outpost", _"Site", _"Expedition", _"Enclave" }
|
||||
|
||||
local STR_BONUS_ALTAR_NAMES = { _"Rest", _"Passage", _"Ruin", _"Lair", _"Oracle", _"Altar", _"Secret", _"Ossuary", _"Conclave", _"Curse", _"Grotto" }
|
||||
|
||||
local STR_BONUS_ALTAR_CRYSTAL_NAMES = { _"Passage", _"Lair", _"Curse", _"Domain", _"Bane", _"Cave", _"Secret" }
|
||||
|
||||
local STR_BONUS_TEMPLE_NAMES = { _"Rest", _"Ruin", _"Lair", _"Oracle", _"Temple", _"Sanctuary", _"Shrine", _"Conclave", _"Refuge", _"Library", _"Academy", _"School", _"Mausoleum", _"Crypt", _"Memory" }
|
||||
|
||||
local STR_BONUS_TEMPLE_ROAD_NAMES = { _"Rest", _"Route", _"Oracle", _"Temple", _"Sanctuary", _"Shrine", _"Refuge", _"Road", _"Library", _"Path", _"Market", _"Academy", _"School", _"Conclave", _"Mausoleum", _"Crypt" }
|
||||
|
||||
local STR_BONUS_TEMPLE_GRASS_NAMES = { _"Rest", _"Ruin", _"Oracle", _"Temple", _"Sanctuary", _"Shrine", _"Refuge", _"Library", _"Academy", _"School", _"Conclave", _"Mausoleum", _"Crypt", _"Market" }
|
||||
|
||||
local STR_BONUS_TEMPLE_MOUNTAIN_NAMES = { _"Rest", _"Passage", _"Ruin", _"Lair", _"Exile", _"Oracle", _"Temple", _"Sanctuary", _"Shrine", _"Refuge", _"Peak", _"Domain", _"Conclave", _"Mausoleum", _"Crypt", _"Memory" }
|
||||
|
||||
local STR_BONUS_TEMPLE_HILLS_NAMES = { _"Rest", _"Passage", _"Ruin", _"Lair", _"Refuge", _"Cliff", _"Domain", _"Route", _"Sanctuary", _"Conclave", _"Temple", _"Shrine", _"Oracle", _"Crypt", _"Mausoleum", _"Route" }
|
||||
|
||||
local STR_BONUS_TEMPLE_GREEN_NAMES = { _"Rest", _"Passage", _"Ruin", _"Lair", _"Exile", _"Oracle", _"Domain", _"Curse", _"Bane", _"Vestige", _"Perversion", _"Decay", _"Moor", _"Crypt", _"Mausoleum", _"Ossuary" }
|
||||
|
||||
local STR_BONUS_TREE_NAMES = { _"Conclave", _"Enclave", _"Meadow", _"Prairie", _"Field", _"Route", _"Refuge", _"Tree", _"Glade", _"Domain", _"Shire" }
|
||||
|
||||
local STR_BONUS_ROCK_TOWER_NAMES = { _"Rest", _"Vestige", _"Lair", _"Domain", _"Tower", _"Ruin", _"Refuge", _"Sanctuary", _"Observatory", _"Observatory", _"Enclave", _"Conclave", _"Crypt" }
|
||||
|
||||
local STR_BONUS_ROCK_SWAMP_NAMES = { _"Rest", _"Point", _"Decay", _"Passage", _"Ruin", _"Lair", _"Exile", _"Bog", _"Domain", _"Bane", _"Curse", _"Vestige", _"Secret" }
|
||||
|
||||
local STR_BONUS_GENERIC_NAMES = { _"Rest", _"Point", _"Passage", _"Ruin", _"Lair", _"Exile", _"Vestige" }
|
||||
|
||||
local strings = {
|
||||
detritus = STR_BONUS_DETRITUS_NAMES,
|
||||
detritus2 = STR_BONUS_DETRITUS_NAMES,
|
||||
lilies = STR_BONUS_LILIES_NAMES,
|
||||
lilies_s = STR_BONUS_LILIES_SWAMP_NAMES,
|
||||
oak1 = STR_BONUS_TREE_NAMES,
|
||||
oak2 = STR_BONUS_TREE_NAMES,
|
||||
oak3 = STR_BONUS_TREE_NAMES,
|
||||
oak4 = STR_BONUS_TREE_NAMES,
|
||||
oak5 = STR_BONUS_TREE_NAMES,
|
||||
oak6 = STR_BONUS_TREE_NAMES,
|
||||
oak7 = STR_BONUS_TREE_NAMES,
|
||||
oak_dead = STR_BONUS_DEAD_OAK_NAMES,
|
||||
oak_dead2 = STR_BONUS_DEAD_OAK_NAMES,
|
||||
obelisk = STR_BONUS_OBELISK_NAMES,
|
||||
rock1 = STR_BONUS_ROCK_SAND_NAMES,
|
||||
rock3 = STR_BONUS_ROCK_SWAMP_NAMES,
|
||||
rock4 = STR_BONUS_ROCK_NAMES,
|
||||
tower_r1 = STR_BONUS_ROCK_TOWER_NAMES,
|
||||
tower_r4 = STR_BONUS_GENERIC_NAMES,
|
||||
crystal = STR_BONUS_WELL_CRYSTAL_NAMES,
|
||||
crystal3 = STR_BONUS_ALTAR_CRYSTAL_NAMES,
|
||||
ship1 = STR_BONUS_SHIP_NAMES,
|
||||
ship2 = STR_BONUS_SHIP_NAMES,
|
||||
bones = STR_BONUS_BONES_NAMES,
|
||||
bones_s = STR_BONUS_BONES_SWAMP_NAMES,
|
||||
village = STR_BONUS_VILLAGE_RUINED_NAMES,
|
||||
burial = STR_BONUS_BURIAL_NAMES,
|
||||
burial_s = STR_BONUS_BURIAL_SAND_NAMES,
|
||||
burial_c = STR_BONUS_BURIAL_CAVE_NAMES,
|
||||
trapdoor = STR_BONUS_TRAPDOOR_NAMES,
|
||||
coffin = STR_BONUS_COFFIN_NAMES,
|
||||
mine = STR_BONUS_MINE_NAMES,
|
||||
doors = STR_BONUS_DOORS_NAMES,
|
||||
tent1 = STR_BONUS_TENT_NAMES,
|
||||
shelter = STR_BONUS_SHELTER_NAMES,
|
||||
tent2 = STR_BONUS_TENT_NAMES,
|
||||
tent2_g = STR_BONUS_TENT_FANCY_GRASS_NAMES,
|
||||
tent2_r = STR_BONUS_TENT_FANCY_ROAD_NAMES,
|
||||
shop = STR_BONUS_SHOP_NAMES,
|
||||
shop_g = STR_BONUS_SHOP_GRASS_NAMES,
|
||||
outpost = STR_BONUS_TENT_OUTPOST_NAMES,
|
||||
signpost = STR_BONUS_SIGNPOST_NAMES,
|
||||
rock_cairn = STR_BONUS_ROCK_CAIRN_NAMES,
|
||||
rock_cairn_c = STR_BONUS_ROCK_CAIRN_CAVE_NAMES,
|
||||
dolmen = STR_BONUS_DOLMEN_NAMES,
|
||||
monolith1 = STR_BONUS_MONOLITH_HILLS_NAMES,
|
||||
monolith1_r = STR_BONUS_GENERIC_NAMES,
|
||||
monolith2 = STR_BONUS_MONOLITH_NAMES,
|
||||
monolith3 = STR_BONUS_ROCK_NAMES,
|
||||
dolmen_g = STR_BONUS_DOLMEN_GRASS_NAMES,
|
||||
monolith4 = STR_BONUS_MONOLITH_HILLS_NAMES,
|
||||
monolith4_r = STR_BONUS_GENERIC_NAMES,
|
||||
well_g = STR_BONUS_WELL_GRASS_NAMES,
|
||||
well_r = STR_BONUS_WELL_ROAD_NAMES,
|
||||
well = STR_BONUS_WELL_CAVE_NAMES,
|
||||
lighthouse = STR_BONUS_LIGHTHOUSE_NAMES,
|
||||
campfire = STR_BONUS_CAMPFIRE_NAMES,
|
||||
temple = STR_BONUS_TEMPLE_NAMES,
|
||||
temple2 = STR_BONUS_TEMPLE_ROAD_NAMES,
|
||||
temple2_g = STR_BONUS_TEMPLE_GRASS_NAMES,
|
||||
temple3 = STR_BONUS_TEMPLE_MOUNTAIN_NAMES,
|
||||
temple4 = STR_BONUS_TEMPLE_HILLS_NAMES,
|
||||
temple_green_h = STR_BONUS_TEMPLE_GREEN_NAMES,
|
||||
temple_green_h2 = STR_BONUS_TEMPLE_GREEN_NAMES,
|
||||
temple_green_g = STR_BONUS_TEMPLE_GREEN_NAMES,
|
||||
temple_green_g2 = STR_BONUS_TEMPLE_GREEN_NAMES,
|
||||
altar = STR_BONUS_ALTAR_NAMES,
|
||||
windmill = STR_BONUS_WINDMILL_NAMES
|
||||
}
|
||||
|
||||
local IMG_DETRITUS = "misc/blank-hex.png~BLIT(terrain/misc/detritus/detritusC-3.png~CROP(0,18,66,54),6,13)~BLIT(terrain/misc/detritus/detritusC-2.png~CROP(8,0,35,70),0,2)~BLIT(terrain/misc/detritus/detritusC-2.png~CROP(43,44,29,26),36,46)"
|
||||
|
||||
local IMG_DETRITUS_2 = "misc/blank-hex.png~BLIT(terrain/misc/detritus/detritusC-2.png~CROP(0,4,59,68),13,0)~BLIT(terrain/misc/detritus/detritusC-5.png~CROP(17,0,55,63),0,9)"
|
||||
|
||||
local IMG_LILIES = "terrain/embellishments/water-lilies-flower-small4.png~BLIT(terrain/embellishments/water-lilies-flower-small5.png~CROP(40,28,17,17),40,28)"
|
||||
|
||||
local IMG_LILIES_2 = "misc/blank-hex.png~BLIT(terrain/embellishments/water-lilies-flower5.png~CROP(21,12,72,72)~BLIT(terrain/embellishments/water-lilies-flower-small2.png~CROP(0,8,55,64),17,0)"
|
||||
|
||||
local IMG_OAK_1 = "terrain/embellishments/flowers-mixed4.png~MASK(scenery/whirlpool.png)~BLIT(scenery/oak-leaning.png)"
|
||||
|
||||
local IMG_OAK_2 = "terrain/embellishments/flowers-mixed3.png~MASK(scenery/whirlpool.png)~BLIT(scenery/oak-leaning.png)"
|
||||
|
||||
-- custom image
|
||||
local IMG_OAK_3 = "scenery/treehouse.png"
|
||||
|
||||
-- custom image
|
||||
local IMG_OAK_4 = "scenery/treehouse.png"
|
||||
|
||||
local IMG_OAK_5 = "terrain/embellishments/flower-purple.png~MASK(scenery/whirlpool.png)~BLIT(scenery/oak-leaning.png)"
|
||||
|
||||
-- custom image
|
||||
local IMG_OAK_6 = "scenery/treehouse.png"
|
||||
|
||||
-- custom image
|
||||
local IMG_OAK_7 = "scenery/treehouse.png"
|
||||
|
||||
local IMG_ROCK_1 = "misc/blank-hex.png~BLIT(scenery/rock1.png~CROP(1,11,71,61),0,0)"
|
||||
|
||||
local IMG_ROCK_3 = "misc/blank-hex.png~BLIT(scenery/rock3.png~CROP(0,11,66,61),6,0)"
|
||||
|
||||
local IMG_ROCK_4 = "misc/blank-hex.png~BLIT(scenery/rock4.png~CROP(0,8,66,64),6,0)"
|
||||
|
||||
-- custom image
|
||||
local IMG_ROCK_1_TOWER = "misc/blank-hex.png~BLIT(scenery/wct-tower.png)"
|
||||
|
||||
-- custom image
|
||||
local IMG_ROCK_4_TOWER = "misc/blank-hex.png~BLIT(scenery/wct-tower.png)"
|
||||
|
||||
-- custom image
|
||||
local IMG_OBELISK_POST = "misc/blank-hex.png~BLIT(scenery/wct-obelisk.png)"
|
||||
|
||||
-- custom image
|
||||
local IMG_ROCK_CAIRN_DOLMEN = "misc/blank-hex.png~BLIT(scenery/wct-dolmen.png~SCALE(75,75)~CROP(0,0,72,62),0,10)"
|
||||
|
||||
-- custom image
|
||||
local IMG_MONOLITH_DOLMEN = "misc/blank-hex.png~BLIT(scenery/wct-dolmen2.png~SCALE(75,75)~CROP(0,0,72,62),0,10)"
|
||||
|
||||
-- custom image
|
||||
local IMG_TEMPLE_2 = "misc/blank-hex.png~BLIT(scenery/wct-temple.png~SCALE(60,60),6,3)"
|
||||
|
||||
-- custom image
|
||||
local IMG_TEMPLE_3 = "scenery/wct-temple2.png"
|
||||
|
||||
-- custom image
|
||||
local IMG_TEMPLE_GREEN_HILLS = "misc/blank-hex.png~BLIT(scenery/wct-temple4.png~SCALE(65,65),4,4)"
|
||||
|
||||
-- custom image
|
||||
local IMG_TEMPLE_GREEN_HILLS_2 = "misc/blank-hex.png~BLIT(scenery/wct-temple5.png~SCALE(63,63),6,2)"
|
||||
|
||||
-- custom image
|
||||
local IMG_TEMPLE_GREEN_GRASS = "misc/blank-hex.png~BLIT(scenery/wct-temple3.png)"
|
||||
|
||||
-- custom image
|
||||
local IMG_TEMPLE_GREEN_GRASS_2 = "misc/blank-hex.png~BLIT(scenery/wct-temple5.png~SCALE(63,63),6,2)"
|
||||
|
||||
-- custom image
|
||||
local IMG_DETRITUS_OAK_1 = "scenery/wct-oak-dead.png"
|
||||
|
||||
-- custom image
|
||||
local IMG_DETRITUS_OAK_2 = "scenery/wct-oak-dead2.png"
|
||||
|
||||
-- custom image
|
||||
local IMG_CRYSTAL_WELL = "scenery/wct-crystal.png"
|
||||
|
||||
-- custom image
|
||||
local IMG_CRYSTALS_ALTAR = "misc/blank-hex.png~BLIT(scenery/wct-crystal3.png~SCALE(59,59),6,4)"
|
||||
|
||||
-- custom image
|
||||
local IMG_TENT_OUTPOST = "scenery/wct-outpost.png"
|
||||
|
||||
|
||||
local images = {
|
||||
rock1 = IMG_ROCK_1,
|
||||
rock3 = IMG_ROCK_3,
|
||||
rock4 = IMG_ROCK_4,
|
||||
tower_r1 = IMG_ROCK_1_TOWER,
|
||||
tower_r4 = IMG_ROCK_4_TOWER,
|
||||
lilies = IMG_LILIES,
|
||||
lilies_s = IMG_LILIES_2,
|
||||
detritus = IMG_DETRITUS,
|
||||
detritus2 = IMG_DETRITUS_2,
|
||||
oak1 = IMG_OAK_1,
|
||||
oak2 = IMG_OAK_2,
|
||||
oak3 = IMG_OAK_3,
|
||||
oak4 = IMG_OAK_4,
|
||||
oak5 = IMG_OAK_5,
|
||||
oak6 = IMG_OAK_6,
|
||||
oak7 = IMG_OAK_7,
|
||||
obelisk = IMG_OBELISK_POST,
|
||||
dolmen = IMG_ROCK_CAIRN_DOLMEN,
|
||||
dolmen_g = IMG_MONOLITH_DOLMEN,
|
||||
oak_dead = IMG_DETRITUS_OAK_1,
|
||||
oak_dead2 = IMG_DETRITUS_OAK_2,
|
||||
crystal = IMG_CRYSTAL_WELL,
|
||||
crystal3 = IMG_CRYSTALS_ALTAR,
|
||||
outpost = IMG_TENT_OUTPOST,
|
||||
ship1 = "scenery/shipwreck-1.png",
|
||||
ship2 = "scenery/wreck.png",
|
||||
bones = "items/bones.png",
|
||||
bones_s = "items/bones.png",
|
||||
village = "scenery/village-human-burned2.png",
|
||||
burial = "items/burial.png",
|
||||
burial_s = "items/burial.png",
|
||||
burial_c = "items/burial.png",
|
||||
trapdoor = "scenery/trapdoor-open.png",
|
||||
coffin = "items/coffin-closed.png",
|
||||
mine = "scenery/mine-abandoned.png",
|
||||
doors = "scenery/dwarven-doors-closed.png",
|
||||
tent1 = "scenery/tent-ruin-1.png",
|
||||
shelter = "scenery/tent-ruin-1.png",
|
||||
tent2 = "scenery/tent-fancy-red.png",
|
||||
tent2_g = "scenery/tent-fancy-red.png",
|
||||
tent2_r = "scenery/tent-fancy-red.png",
|
||||
shop = "scenery/tent-shop-weapons.png",
|
||||
shop_g = "scenery/tent-shop-weapons.png",
|
||||
signpost = "scenery/signpost.png",
|
||||
rock_cairn = "scenery/rock-cairn.png",
|
||||
rock_cairn_c = "scenery/rock-cairn.png",
|
||||
monolith1 = "scenery/monolith1.png",
|
||||
monolith1_r = "scenery/monolith1.png",
|
||||
monolith2 = "scenery/monolith2.png",
|
||||
monolith3 = "scenery/monolith3.png",
|
||||
monolith4 = "scenery/monolith4.png",
|
||||
monolith4_r = "scenery/monolith4.png",
|
||||
well_g = "scenery/well.png",
|
||||
well_r = "scenery/well.png",
|
||||
well = "scenery/well.png",
|
||||
lighthouse = "scenery/lighthouse.png",
|
||||
temple = "scenery/temple1.png",
|
||||
temple2 = IMG_TEMPLE_2,
|
||||
temple2_g = IMG_TEMPLE_2,
|
||||
temple3 = IMG_TEMPLE_2,
|
||||
temple4 = IMG_TEMPLE_3,
|
||||
temple_green_h = IMG_TEMPLE_GREEN_HILLS,
|
||||
temple_green_h2 = IMG_TEMPLE_GREEN_HILLS_2,
|
||||
temple_green_g = IMG_TEMPLE_GREEN_GRASS,
|
||||
temple_green_g2 = IMG_TEMPLE_GREEN_GRASS_2,
|
||||
altar = "items/altar.png",
|
||||
}
|
||||
return strings, images
|
69
data/campaigns/World_Conquest/lua/game_mechanics/color.lua
Normal file
|
@ -0,0 +1,69 @@
|
|||
local color = {}
|
||||
|
||||
function color.to_pango_string(c)
|
||||
return ("#%02x%02x%02x"):format(c.r, c.g, c.b)
|
||||
end
|
||||
|
||||
function color.color_text(color_str, text)
|
||||
return "<span color='" .. color_str .. "'>" .. text .. "</span>"
|
||||
end
|
||||
|
||||
|
||||
function color.bonus_text(str)
|
||||
return color.color_text("#ff75ff", str)
|
||||
end
|
||||
|
||||
function color.help_text(str)
|
||||
return color.color_text("#ff95ff", str)
|
||||
end
|
||||
|
||||
-- note: the default argument for the first parameter is the
|
||||
-- currently active side, not the currently viewing side
|
||||
function color.tc_text(team_num, text)
|
||||
if text == nil then
|
||||
text = team_num
|
||||
team_num = wesnoth.current.side
|
||||
end
|
||||
local c = wesnoth.colors[wesnoth.sides[team_num].color].mid
|
||||
|
||||
local color_str = color.to_pango_string(c)
|
||||
return color.color_text(color_str, text)
|
||||
end
|
||||
|
||||
function color.tc_image(team_num, img)
|
||||
if img == nil then
|
||||
img = team_num
|
||||
team_num = wesnoth.current.side
|
||||
end
|
||||
return img .. "~TC(" .. team_num .. ",magenta)"
|
||||
end
|
||||
|
||||
-- Fixes the colors in mp campaigns: in case that the players changed the
|
||||
-- colors in the mp setup screen, we have to remember those settings and
|
||||
-- set the teams color in later scenarios acccordingly.
|
||||
function wesnoth.wml_actions.wc2_fix_colors(cfg)
|
||||
local player_sides = wesnoth.get_sides(wml.get_child(cfg, "player_sides"))
|
||||
local other_sides = wesnoth.get_sides { { "not", wml.get_child(cfg, "player_sides") } }
|
||||
local available_colors = { "red", "blue", "green", "purple", "black", "brown", "orange", "white", "teal" }
|
||||
local taken_colors = {}
|
||||
|
||||
for i, side in ipairs(player_sides) do
|
||||
if side.variables.wc2_color then
|
||||
side.color = side.variables.wc2_color
|
||||
else
|
||||
side.variables.wc2_color = side.color
|
||||
end
|
||||
taken_colors[side.color] = true
|
||||
end
|
||||
|
||||
local color_num = 1
|
||||
for i, side in ipairs(other_sides) do
|
||||
while taken_colors[available_colors[color_num]] == true do
|
||||
color_num = color_num + 1
|
||||
end
|
||||
side.color = available_colors[color_num]
|
||||
taken_colors[side.color] = true
|
||||
end
|
||||
end
|
||||
|
||||
return color
|
156
data/campaigns/World_Conquest/lua/game_mechanics/dropping.lua
Normal file
|
@ -0,0 +1,156 @@
|
|||
-- general code related to dropping items, code taken from 'scenario with robots' add-on.
|
||||
-- todo: maybe we coudl mainline this and merge it with the iterms.lua code ( this means
|
||||
-- adding a mainline "pickup item" event that fires when a unit steops on an [item] and
|
||||
-- would have the same features as this here)
|
||||
local on_event = wesnoth.require("on_event")
|
||||
|
||||
local dropping = {}
|
||||
|
||||
dropping.field_data = {}
|
||||
|
||||
dropping.loc_to_index = function(x,y)
|
||||
return (y - 1) * 1000 + x
|
||||
end
|
||||
|
||||
dropping.index_to_loc = function(index)
|
||||
local y_m1 = math.floor(index / 1000)
|
||||
return index - y_m1 * 1000, y_m1 + 1
|
||||
end
|
||||
|
||||
dropping.decorate_imagename = function(id)
|
||||
return "wc2_item_" .. id
|
||||
end
|
||||
|
||||
dropping.place_image = function(x, y, cfg)
|
||||
wesnoth.add_tile_overlay(x, y, {
|
||||
image = cfg.image,
|
||||
team_name = cfg.team_name,
|
||||
visible_in_fog = cfg.visible_in_fog,
|
||||
redraw = cfg.redraw,
|
||||
name = dropping.decorate_imagename(cfg.id),
|
||||
z_order = cfg.z_order
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
-- this can be used to remove item but not to add items.
|
||||
dropping.get_entries_at_readonly = function(x,y)
|
||||
return dropping.field_data[dropping.loc_to_index(x,y)] or {}
|
||||
end
|
||||
|
||||
dropping.get_entries_at_readwrite = function(x,y)
|
||||
local index = dropping.loc_to_index(x,y)
|
||||
dropping.field_data[index] = dropping.field_data[index] or {}
|
||||
return dropping.field_data[index]
|
||||
end
|
||||
|
||||
dropping.remove_empty_lists = function()
|
||||
local to_delete = {}
|
||||
for k,v in pairs(dropping.field_data) do
|
||||
if #v == 0 then
|
||||
to_delete[k] = true
|
||||
end
|
||||
end
|
||||
for k,v in pairs(to_delete) do
|
||||
dropping.field_data[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
dropping.add_item = function(x, y, cfg)
|
||||
table.insert(dropping.get_entries_at_readwrite(x,y), cfg)
|
||||
cfg.id = dropping.next_id
|
||||
dropping.next_id = dropping.next_id + 1
|
||||
dropping.place_image(x, y, cfg)
|
||||
end
|
||||
|
||||
dropping.remove_item = function(x, y, id)
|
||||
local entries = dropping.get_entries_at_readwrite(x,y)
|
||||
for i,v in ipairs(entries) do
|
||||
if v.id == id then
|
||||
wesnoth.remove_tile_overlay(x, y, dropping.decorate_imagename(id))
|
||||
table.remove(entries, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
dropping.remove_all_items = function(filter)
|
||||
for k,v in pairs(dropping.field_data) do
|
||||
local start = #v
|
||||
local x, y = dropping.index_to_loc(k)
|
||||
for i = start, 1, -1 do
|
||||
if filter(v[i], x, y) then
|
||||
wesnoth.remove_tile_overlay(x, y, dropping.decorate_imagename(v[i].id))
|
||||
table.remove(v, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
dropping.remove_current_item = function()
|
||||
local v = dropping.current_item
|
||||
local ec = wesnoth.current.event_context
|
||||
wesnoth.remove_tile_overlay(ec.x1, ec.y1, dropping.decorate_imagename(v.id))
|
||||
dropping.item_taken = true
|
||||
end
|
||||
|
||||
|
||||
wesnoth.persistent_tags.wc2_dropping.write = function(add)
|
||||
local res = {
|
||||
next_id = dropping.next_id,
|
||||
}
|
||||
for i,v in pairs(dropping.field_data) do
|
||||
local x,y = dropping.index_to_loc(i)
|
||||
for i2,v2 in ipairs(v) do
|
||||
table.insert(res, wml.tag.item {
|
||||
x = x,
|
||||
y = y,
|
||||
wml.tag.data (v2)
|
||||
})
|
||||
end
|
||||
end
|
||||
add(res)
|
||||
end
|
||||
-- read might not be called if there is no [dropped_items] tag found
|
||||
wesnoth.persistent_tags.wc2_dropping.read = function(cfg)
|
||||
for item in wml.child_range(cfg, "item") do
|
||||
local hex_list = dropping.get_entries_at_readwrite(item.x, item.y)
|
||||
table.insert(hex_list, (wml.get_child(item, "data")))
|
||||
end
|
||||
dropping.next_id = cfg.next_id or 0
|
||||
dropping.remove_empty_lists()
|
||||
end
|
||||
|
||||
on_event("moveto", function(event_context)
|
||||
local x = event_context.x1
|
||||
local y = event_context.y1
|
||||
local entries = dropping.get_entries_at_readonly(x,y)
|
||||
local i = 1
|
||||
while i <= #entries do
|
||||
local v = entries[i]
|
||||
dropping.current_item = v
|
||||
dropping.item_taken = nil
|
||||
wesnoth.fire_event("wc2_drop_pickup", x, y)
|
||||
if dropping.item_taken then
|
||||
table.remove(entries, i)
|
||||
wesnoth.remove_tile_overlay(x, y, dropping.decorate_imagename(v.id))
|
||||
wesnoth.allow_undo(false)
|
||||
else
|
||||
i = i + 1
|
||||
end
|
||||
dropping.current_item = nil
|
||||
dropping.item_taken = nil
|
||||
end
|
||||
end)
|
||||
|
||||
on_event("preload", function()
|
||||
dropping.next_id = dropping.next_id or 0
|
||||
for k,v in pairs(dropping.field_data) do
|
||||
local x,y = dropping.index_to_loc(k)
|
||||
for i, cfg in ipairs(v) do
|
||||
dropping.place_image(x, y, cfg)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
return dropping
|
171
data/campaigns/World_Conquest/lua/game_mechanics/effects.lua
Normal file
|
@ -0,0 +1,171 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local helper = wesnoth.require("helper")
|
||||
local T = wml.tag
|
||||
|
||||
local terrain_map = { fungus = "Uft", cave = "Ut", sand = "Dt",
|
||||
reef = "Wrt", hills = "Ht", swamp_water = "St", shallow_water = "Wst", castle = "Ct",
|
||||
mountains = "Mt", deep_water = "Wdt", flat = "Gt", forest = "Ft", frozen = "At",
|
||||
village = "Vt", impassable = "Xt", unwalkable = "Qt", rails = "Rt"
|
||||
}
|
||||
|
||||
-- for all attacks that match [filter_attack], it add a dublicate fo that attack and modifres is as describes in the [attack] subtag which uses the apply_to=attack syntax
|
||||
function wesnoth.effects.wc2_optional_attack(u, cfg)
|
||||
local name_suffix = cfg.name_suffix or helper.wml_error("apply_to=wc2_optional_attack missing required name_suffix= attribute.")
|
||||
local attack_mod = wml.get_child(cfg, "attack") or helper.wml_error("apply_to=wc2_optional_attack missing required [attack] subtag")
|
||||
local attacks_to_add = {}
|
||||
local names = {}
|
||||
for i = 1, #u.attacks do
|
||||
local attack = u.attacks[i]
|
||||
if attack:matches(wml.get_child(cfg, "filter_attack")) then
|
||||
local new_name = attack.name .. name_suffix
|
||||
local new_attack = attack.__cfg
|
||||
new_attack.name = new_name
|
||||
new_attack.apply_to = "new_attack"
|
||||
table.insert(names, new_name)
|
||||
table.insert(attacks_to_add, new_attack)
|
||||
end
|
||||
end
|
||||
for k,v in ipairs(attacks_to_add) do
|
||||
wesnoth.add_modification(u, "object", { T.effect ( v)}, false)
|
||||
end
|
||||
|
||||
if #names > 0 then
|
||||
-- if names is empty then it would give 'name=""' which would match all attacks.
|
||||
attack_mod.apply_to = "attack"
|
||||
attack_mod.name = table.concat(names, ",")
|
||||
|
||||
wesnoth.add_modification(u, "object", { T.effect (attack_mod) }, false)
|
||||
end
|
||||
end
|
||||
|
||||
-- The implementation of the moves defense bonus in movement training.
|
||||
function wesnoth.effects.wc2_moves_defense(u, cfg)
|
||||
wesnoth.add_modification(u, "object", { T.effect {
|
||||
apply_to = "defense",
|
||||
replace = false,
|
||||
T.defense {
|
||||
fungus = -u.max_moves,
|
||||
cave = -u.max_moves,
|
||||
deep_water = -u.max_moves,
|
||||
shallow_water = -u.max_moves,
|
||||
swamp_water = -u.max_moves,
|
||||
flat = -u.max_moves,
|
||||
sand = -u.max_moves,
|
||||
forest = -u.max_moves,
|
||||
hills = -u.max_moves,
|
||||
mountains = -u.max_moves,
|
||||
village = -u.max_moves,
|
||||
castle = -u.max_moves,
|
||||
frozen = -u.max_moves,
|
||||
unwalkable = -u.max_moves,
|
||||
reef = -u.max_moves,
|
||||
},
|
||||
}}, false)
|
||||
end
|
||||
|
||||
-- Like apply_to=resistance with replace=true, but never decreases resistances.
|
||||
function wesnoth.effects.wc2_min_resistance(u, cfg)
|
||||
local resistance_new = {}
|
||||
local resistance_old = wml.parsed(wml.get_child(cfg, "resistance"))
|
||||
local unit_resistance_cfg = nil
|
||||
for k,v in pairs(resistance_old) do
|
||||
if type(k) == "string" and type(v) == "number" then
|
||||
if not unit_resistance_cfg then
|
||||
unit_resistance_cfg = wml.parsed(wml.get_child(u.__cfg, "resistance"))
|
||||
end
|
||||
if unit_resistance_cfg[k] >= v then
|
||||
resistance_new[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
wesnoth.add_modification(u, "object", {
|
||||
T.effect {
|
||||
apply_to = "resistance",
|
||||
replace = true,
|
||||
T.resistance (resistance_new),
|
||||
},
|
||||
}, false)
|
||||
end
|
||||
|
||||
|
||||
-- Like apply_to=defense with replace=true, but never decreases defense.
|
||||
function wesnoth.effects.wc2_min_defense(u, cfg)
|
||||
local defense_new = {}
|
||||
local defense_old = wml.parsed(wml.get_child(cfg, "defense"))
|
||||
for k,v in pairs(defense_old) do
|
||||
if type(k) == "string" and type(v) == "number" and wesnoth.unit_defense(u, terrain_map[k] or "") >= v then
|
||||
defense_new[k] = v
|
||||
end
|
||||
end
|
||||
wesnoth.add_modification(u, "object", {
|
||||
T.effect {
|
||||
apply_to = "defense",
|
||||
replace = true,
|
||||
T.defense (defense_new),
|
||||
},
|
||||
}, false)
|
||||
end
|
||||
|
||||
-- Sets the auro accordingly if unit might have multiple of illumination, darkness or forcefield abilities.
|
||||
function wesnoth.effects.wc2_update_aura(u, cfg)
|
||||
local illuminates = wesnoth.match_unit(u, { ability = "illumination" } )
|
||||
local darkens = wesnoth.match_unit(u, { ability = "darkness" } )
|
||||
local forcefield = wesnoth.match_unit(u, { ability = "forcefield" } )
|
||||
local halo = ""
|
||||
if illuminates and darkens then
|
||||
wesnoth.message("WC2", "Warning illuminates and darkens discovered on a unit")
|
||||
end
|
||||
if forcefield and illuminates then
|
||||
halo = "halo/illuminates-aura.png~R(50)"
|
||||
elseif forcefield and darkens then
|
||||
halo = "halo/darkens-aura.png~R(40)"
|
||||
elseif forcefield then
|
||||
halo = "halo/darkens-aura.png~O(65%)~R(150)"
|
||||
elseif darkens then
|
||||
halo = "halo/darkens-aura.png"
|
||||
elseif illuminates then
|
||||
halo = "halo/illuminates-aura.png"
|
||||
end
|
||||
|
||||
wesnoth.add_modification(u, "object", {
|
||||
T.effect {
|
||||
apply_to = "halo",
|
||||
halo = halo,
|
||||
},
|
||||
}, false)
|
||||
end
|
||||
|
||||
-- Similar to the usual apply_to=overlay effect but does not add overlays the the unit already has.
|
||||
function wesnoth.effects.wc2_overlay(u, cfg)
|
||||
if cfg.add then
|
||||
local to_add_old = wc2_utils.split_to_array(cfg.add)
|
||||
local to_add_new = {}
|
||||
local current = u.overlays
|
||||
for i1,v1 in ipairs(to_add_old) do
|
||||
local has_already = false
|
||||
for i2,v2 in ipairs(current) do
|
||||
if v2 == v1 then
|
||||
has_already = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not has_already then
|
||||
table.insert(to_add_new, v1)
|
||||
end
|
||||
end
|
||||
cfg.add = table.concat(to_add_new,",")
|
||||
end
|
||||
cfg.apply_to = "overlay"
|
||||
wesnoth.add_modification(u, "object", { T.effect(cfg)} , false)
|
||||
end
|
||||
|
||||
-- Can move in same turn as when recruited/recalled
|
||||
function wesnoth.effects.wc2_move_on_recruit(u, cfg)
|
||||
u.variables["mods.wc2_move_on_recruit"] = true
|
||||
end
|
||||
|
||||
-- The implementation of this mods reduced recall costs, all units get an object with this effect.
|
||||
function wesnoth.effects.wc2_recall_cost(u, cfg)
|
||||
local t = wesnoth.unit_types[u.type]
|
||||
u.recall_cost = math.min(20, t.cost + 3)
|
||||
end
|
130
data/campaigns/World_Conquest/lua/game_mechanics/heroes.lua
Normal file
|
@ -0,0 +1,130 @@
|
|||
local helper = wesnoth.require("helper")
|
||||
local T = wml.tag
|
||||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
|
||||
local wc2_heroes = {}
|
||||
-- an array of wml tables, usually containing type,
|
||||
wc2_heroes.commander_overlay = "misc/wct-commander.png"
|
||||
wc2_heroes.hero_overlay = "misc/hero-icon.png"
|
||||
wc2_heroes.dialogues = {}
|
||||
wc2_heroes.trait_heroic = nil
|
||||
wc2_heroes.trait_expert = nil
|
||||
|
||||
if wesnoth.have_file("./unittypedata.lua") then
|
||||
local data = wesnoth.require("./unittypedata.lua")
|
||||
for v,k in pairs(data) do
|
||||
wc2_heroes.dialogues[v] = k
|
||||
end
|
||||
end
|
||||
|
||||
function wc2_heroes.find_dialogue(t)
|
||||
return wc2_heroes.dialogues[t] or wc2_heroes.dialogues.default
|
||||
end
|
||||
|
||||
function wc2_heroes.init_data()
|
||||
local cfg_heroic = wc2_utils.get_wc2_data("trait_heroic")
|
||||
local cfg_expert = wc2_utils.get_wc2_data("trait_expert")
|
||||
wc2_heroes.trait_heroic = wml.get_child(wml.get_child(cfg_heroic, "trait_heroic"), "trait")
|
||||
wc2_heroes.trait_expert = wml.get_child(wml.get_child(cfg_expert, "trait_expert"), "trait")
|
||||
end
|
||||
|
||||
function wc2_heroes.commander_overlay_object()
|
||||
return wml.tag.object {
|
||||
id = "wc2_commander_overlay",
|
||||
wml.tag.effect {
|
||||
apply_to="overlay",
|
||||
add = wc2_heroes.commander_overlay
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function wc2_heroes.hero_overlay_object()
|
||||
return wml.tag.object {
|
||||
id = "wc2_hero_overlay",
|
||||
wml.tag.effect {
|
||||
apply_to="overlay",
|
||||
add = wc2_heroes.hero_overlay
|
||||
}
|
||||
}
|
||||
end
|
||||
-- @a t the unit type id
|
||||
-- @returns the content of [modifications] for a unit.
|
||||
function wc2_heroes.generate_traits(t)
|
||||
local res = {}
|
||||
|
||||
if wc2_heroes.trait_heroic then
|
||||
table.insert(res, wml.tag.trait (wc2_heroes.trait_heroic))
|
||||
end
|
||||
for k,v in ipairs(wc2_era.hero_traits) do
|
||||
if v.types[t] then
|
||||
table.insert(res, wml.tag.trait (v.trait))
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
-- @a t the unit type
|
||||
function wc2_heroes.place(t, side, x, y, is_commander)
|
||||
--print("wc2_heroes.place type=" .. t .. " side=" .. side)
|
||||
|
||||
local modifications = wc2_heroes.generate_traits(t)
|
||||
table.insert(modifications, 1, wml.tag.advancement { wc2_scenario.experience_penalty() })
|
||||
|
||||
table.insert(
|
||||
modifications,
|
||||
is_commander and wc2_heroes.commander_overlay_object() or wc2_heroes.hero_overlay_object()
|
||||
)
|
||||
local u = wesnoth.create_unit {
|
||||
type = t,
|
||||
side = side,
|
||||
random_traits = false,
|
||||
role = is_commander and "commander" or nil,
|
||||
wml.tag.modifications (modifications),
|
||||
}
|
||||
if is_commander then
|
||||
u.variables["wc2.is_commander"] = true
|
||||
end
|
||||
local x2,y2 = wesnoth.find_vacant_tile(x, y, u)
|
||||
u:to_map(x2,y2)
|
||||
return u
|
||||
end
|
||||
|
||||
function wesnoth.wml_actions.wc2_random_hero(cfg)
|
||||
local side_num = cfg.side or helper.wml_error("missing side= attribute in [wc2_initial_hero]")
|
||||
local x = cfg.x or helper.wml_error("missing x= attribute in [wc2_initial_hero]")
|
||||
local y = cfg.y or helper.wml_error("missing y= attribute in [wc2_initial_hero]")
|
||||
local t = wc2_era.pick_deserter(side_num)
|
||||
|
||||
if t == nil then
|
||||
print("No serserter available for side", side_num)
|
||||
return
|
||||
end
|
||||
wc2_heroes.place(t, side_num, x, y)
|
||||
end
|
||||
|
||||
-- prints the dialoge when @finder finds @found from a unit type, both parameters are lua unit objects.
|
||||
function wc2_heroes.founddialouge(finder, found)
|
||||
local type_dialogue = wc2_heroes.find_dialogue(found.type)
|
||||
wesnoth.wml_actions.message {
|
||||
id = found.id,
|
||||
message = type_dialogue.founddialogue,
|
||||
}
|
||||
local reply = type_dialogue.reply or wc2_heroes.dialogues.default.reply
|
||||
|
||||
for i, alt_replay in ipairs(type_dialogue.alt_reply or {}) do
|
||||
local function matches(attr)
|
||||
return string.match(alt_replay[attr] or "", finder[attr])
|
||||
end
|
||||
if matches("race") or matches("gender") or matches("type") then
|
||||
reply = alt_replay.reply
|
||||
end
|
||||
end
|
||||
wesnoth.wml_actions.message {
|
||||
id = finder.id,
|
||||
message = reply,
|
||||
}
|
||||
end
|
||||
|
||||
wc2_heroes.init_data()
|
||||
|
||||
return wc2_heroes
|
|
@ -0,0 +1,178 @@
|
|||
local on_event = wesnoth.require("on_event")
|
||||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
|
||||
local wc2_invest = {}
|
||||
|
||||
function wc2_invest.add_items(side_num, num_items)
|
||||
local side = wesnoth.sides[side_num]
|
||||
local items_left = wc2_utils.split_to_array(side.variables["wc2.items_left"])
|
||||
local items_available = wc2_utils.split_to_array(side.variables["wc2.items"])
|
||||
for j = 1, num_items do
|
||||
local i = wesnoth.random(#items_left)
|
||||
table.insert(items_available, items_left[i])
|
||||
table.remove(items_left, i)
|
||||
end
|
||||
|
||||
side.variables["wc2.items_left"] = table.concat(items_left, ",")
|
||||
side.variables["wc2.items"] = table.concat(items_available, ",")
|
||||
end
|
||||
|
||||
|
||||
function wc2_invest.has_items(side_num)
|
||||
local side = wesnoth.sides[side_num]
|
||||
return side.variables["wc2.items"] ~= nil
|
||||
end
|
||||
|
||||
function wc2_invest.initialize()
|
||||
local all_items = {}
|
||||
for i,v in ipairs(wc2_artifacts.get_artifact_list()) do
|
||||
local not_available = wc2_utils.split_to_set(v.not_available or "")
|
||||
if not not_available["player"] then
|
||||
table.insert(all_items, i)
|
||||
end
|
||||
end
|
||||
|
||||
for side_num, side in ipairs(wesnoth.sides) do
|
||||
if wc2_scenario.is_human_side(side_num) then
|
||||
if not wc2_invest.has_items(side_num) then
|
||||
side.variables["wc2.items_left"] = table.concat(all_items, ",")
|
||||
wc2_invest.add_items(side_num, 9)
|
||||
else
|
||||
wc2_invest.add_items(side_num, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
on_event("prestart", function()
|
||||
wc2_invest.initialize()
|
||||
end)
|
||||
|
||||
local function find_index(t, v)
|
||||
for i,v2 in ipairs(t) do
|
||||
if v2 == v then return i end
|
||||
end
|
||||
end
|
||||
|
||||
function wc2_invest.do_gold()
|
||||
local side_num = wesnoth.current.side
|
||||
local side = wesnoth.sides[side_num]
|
||||
local leaders = wesnoth.get_units { side = side_num, canrecruit = true }
|
||||
side.gold = side.gold + 70
|
||||
wesnoth.wml_actions.wc2_map_supply_village {
|
||||
x = leaders[1].x,
|
||||
y = leaders[1].y
|
||||
}
|
||||
end
|
||||
|
||||
function wc2_invest.do_hero(t, is_local)
|
||||
local side_num = wesnoth.current.side
|
||||
local side = wesnoth.sides[side_num]
|
||||
local leaders = wesnoth.get_units { side = side_num, canrecruit = true }
|
||||
local x,y = leaders[1].x, leaders[1].y
|
||||
if t == "wc2_commander" then
|
||||
local commanders = wc2_utils.split_to_array(side.variables["wc2.commanders"])
|
||||
local i = wesnoth.random(#commanders)
|
||||
t = commanders[i]
|
||||
table.remove(commanders, i)
|
||||
side.variables["wc2.commanders"] = table.concat(commanders, ",")
|
||||
if is_local then
|
||||
wc2_invest_tellunit.execute(t)
|
||||
end
|
||||
wc2_heroes.place(t, side_num, x, y, true)
|
||||
elseif t == "wc2_deserter" then
|
||||
|
||||
wesnoth.sides[side_num].gold = wesnoth.sides[side_num].gold + 15
|
||||
|
||||
local deserters = wc2_utils.split_to_array(side.variables["wc2.deserters"])
|
||||
local i = wesnoth.random(#deserters)
|
||||
t = deserters[i]
|
||||
table.remove(deserters, i)
|
||||
side.variables["wc2.deserters"] = table.concat(deserters, ",")
|
||||
if is_local then
|
||||
wc2_invest_tellunit.execute(t)
|
||||
end
|
||||
wc2_heroes.place(t, side_num, x, y, false)
|
||||
else
|
||||
local heroes_available = wc2_utils.split_to_array(side.variables["wc2.heroes"])
|
||||
local i = find_index(heroes_available, t)
|
||||
if i == nil then
|
||||
error("wc2 invest: invalid pick")
|
||||
end
|
||||
table.remove(heroes_available, i)
|
||||
side.variables["wc2.heroes"] = table.concat(heroes_available, ",")
|
||||
wc2_heroes.place(t, side_num, x, y, false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function wc2_invest.do_training(t)
|
||||
local side_num = wesnoth.current.side
|
||||
wc2_training.inc_level(side_num, t)
|
||||
end
|
||||
|
||||
function wc2_invest.do_item(t)
|
||||
local side_num = wesnoth.current.side
|
||||
local side = wesnoth.sides[side_num]
|
||||
local leaders = wesnoth.get_units { side = side_num, canrecruit = true }
|
||||
local x,y = leaders[1].x, leaders[1].y
|
||||
|
||||
local items_available = wc2_utils.split_to_array(side.variables["wc2.items"], {}, tonumber)
|
||||
local i = find_index(items_available, tostring(t))
|
||||
if i == nil then
|
||||
error("wc2 invest: invalid item pick '" .. t .. "' (" .. type(t) ..")")
|
||||
end
|
||||
table.remove(items_available, i)
|
||||
side.variables["wc2.items"] = table.concat(items_available, ",")
|
||||
|
||||
wc2_artifacts.place_item(x, y + 1, t)
|
||||
end
|
||||
|
||||
function wc2_invest.invest()
|
||||
local side_num = wesnoth.current.side
|
||||
local side = wesnoth.sides[side_num]
|
||||
local items_available = wc2_utils.split_to_array(side.variables["wc2.items"])
|
||||
local heroes_available = wc2_utils.split_to_array(side.variables["wc2.heroes"])
|
||||
local commanders_available = wc2_utils.split_to_array(side.variables["wc2.commanders"])
|
||||
local deserters_available = wc2_utils.split_to_array(side.variables["wc2.deserters"])
|
||||
local trainings_available = wc2_training.list_available(side_num, {2,3,4,5,6})
|
||||
local gold_available = true
|
||||
for i =1,2 do
|
||||
local is_local = false
|
||||
local res = wesnoth.synchronize_choice(_"WC2 Invest", function()
|
||||
is_local = true
|
||||
return wc2_show_invest_dialog {
|
||||
items_available = items_available,
|
||||
heroes_available = heroes_available,
|
||||
trainings_available = trainings_available,
|
||||
gold_available = gold_available,
|
||||
deserters_available = deserters_available,
|
||||
commanders_available = commanders_available,
|
||||
}
|
||||
end)
|
||||
if res.pick == "gold" then
|
||||
wc2_invest.do_gold()
|
||||
gold_available = nil
|
||||
elseif res.pick == "hero" then
|
||||
wc2_invest.do_hero(res.type, is_local)
|
||||
heroes_available = nil
|
||||
elseif res.pick == "training" then
|
||||
wc2_invest.do_training(res.type)
|
||||
trainings_available = nil
|
||||
elseif res.pick == "item" then
|
||||
wc2_invest.do_item(res.type)
|
||||
items_available = nil
|
||||
else
|
||||
error("wc2 invest: invalid pick , pick='" .. tostring(res.pick) .. "'.")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function wesnoth.wml_actions.wc2_invest(cfg)
|
||||
--disallow undoing.
|
||||
wesnoth.random(100)
|
||||
wc2_invest.invest()
|
||||
end
|
||||
|
||||
return wc2_invest
|
|
@ -0,0 +1,331 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local T = wml.tag
|
||||
|
||||
local function GUI_FORCE_WIDGET_MINIMUM_SIZE(w,h, content)
|
||||
return T.stacked_widget {
|
||||
definition = "default",
|
||||
T.stack {
|
||||
T.layer {
|
||||
T.row {
|
||||
T.column {
|
||||
T.spacer {
|
||||
definition = "default",
|
||||
width = w,
|
||||
height = h
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
T.layer {
|
||||
T.row {
|
||||
grow_factor = 1,
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_grow = "true",
|
||||
vertical_grow = "true",
|
||||
content
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
local dialog_wml = {
|
||||
maximum_width = 1200,
|
||||
maximum_height = 700,
|
||||
T.helptip { id = "tooltip_large" }, -- mandatory field
|
||||
T.tooltip { id = "tooltip_large" }, -- mandatory field
|
||||
|
||||
T.linked_group { id = "list_image", fixed_width = true },
|
||||
T.linked_group { id = "unit_panel", fixed_width = true },
|
||||
|
||||
T.grid {
|
||||
T.row {
|
||||
grow_factor = 1,
|
||||
T.column {
|
||||
border = "all",
|
||||
border_size = 5,
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
definition = "title",
|
||||
label = _"Invest",
|
||||
id = "title"
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
grow_factor = 1,
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
border = "all",
|
||||
border_size = 5,
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.tree_view {
|
||||
id = "left_tree",
|
||||
definition = "default",
|
||||
horizontal_scrollbar_mode = "never",
|
||||
vertical_scrollbar_mode = "initial_auto",
|
||||
indentation_step_size = 30,
|
||||
T.node {
|
||||
id = "category",
|
||||
T.node_definition {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 0,
|
||||
horizontal_grow = true,
|
||||
T.toggle_button {
|
||||
id = "tree_view_node_toggle",
|
||||
definition = "tree_view_node",
|
||||
},
|
||||
},
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_grow = true,
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
id = "category_name",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
T.node {
|
||||
id = "item_desc",
|
||||
T.node_definition {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_grow = true,
|
||||
T.toggle_panel {
|
||||
id = "tree_view_node_label",
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 0,
|
||||
horizontal_alignment = "left",
|
||||
T.image {
|
||||
id = "image",
|
||||
linked_group = "list_image",
|
||||
},
|
||||
},
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
grow_factor = 1,
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
id = "name",
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
use_markup = true,
|
||||
id = "desc",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
T.node {
|
||||
id = "item",
|
||||
T.node_definition {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_grow = true,
|
||||
T.toggle_panel {
|
||||
id = "tree_view_node_label",
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 0,
|
||||
T.image {
|
||||
id = "image",
|
||||
linked_group = "list_image",
|
||||
},
|
||||
},
|
||||
T.column {
|
||||
horizontal_alignment = "left",
|
||||
grow_factor = 1,
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
id = "name",
|
||||
use_markup = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
T.column { vertical_grow = true, T.grid { T.row {
|
||||
T.column {
|
||||
vertical_grow = true,
|
||||
T.multi_page {
|
||||
id = "details",
|
||||
definition = "default",
|
||||
horizontal_scrollbar_mode = "never",
|
||||
vertical_grow = true,
|
||||
T.page_definition {
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.scroll_label {
|
||||
id = "label",
|
||||
label = "Text",
|
||||
use_markup = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
T.page_definition {
|
||||
id = "hero",
|
||||
T.row {
|
||||
T.column {
|
||||
vertical_grow = true,
|
||||
T.unit_preview_pane {
|
||||
definition = "default",
|
||||
id = "unit",
|
||||
linked_group = "unit_panel",
|
||||
} ,
|
||||
},
|
||||
},
|
||||
},
|
||||
T.page_definition {
|
||||
id = "trailing",
|
||||
--T.row { T.column { T.size_lock { width = 600, height = 900, T.widget { T.grid {
|
||||
--[[
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.label {
|
||||
label = "Before:",
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.scroll_label {
|
||||
id = "training_before",
|
||||
use_markup = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.label {
|
||||
label = "After:",
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.scroll_label {
|
||||
id = "training_after",
|
||||
use_markup = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
--]]
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.scroll_label {
|
||||
id = "details",
|
||||
use_markup = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
--},},},},},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_alignment = "center",
|
||||
T.button {
|
||||
definition = "really_large",
|
||||
label = "Get This Item",
|
||||
id = "ok",
|
||||
}
|
||||
}
|
||||
}
|
||||
},},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
--[[
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
T.spacer {
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
horizontal_alignment = "right",
|
||||
T.button {
|
||||
label = "Ok",
|
||||
id = "ok",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
--]]
|
||||
}
|
||||
}
|
||||
|
||||
return dialog_wml
|
|
@ -0,0 +1,178 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
|
||||
local dialog_wml = wc2_invest_dialog
|
||||
|
||||
|
||||
function wc2_show_invest_dialog_impl(args)
|
||||
local side_num = wesnoth.current.side
|
||||
local available_artifacts = args.items_available
|
||||
local available_heroes = args.heroes_available
|
||||
local available_deserters = args.deserters_available
|
||||
local available_commanders = args.commanders_available
|
||||
local available_training = args.trainings_available
|
||||
|
||||
local show_artifacts = args.items_available ~= nil
|
||||
local show_heroes = args.heroes_available ~= nil
|
||||
local show_training = args.trainings_available ~= nil
|
||||
local show_other = args.gold_available
|
||||
|
||||
local cati_items, cati_heroes, cati_training, cati_other
|
||||
|
||||
local res = nil
|
||||
|
||||
local index_map = {}
|
||||
local details_index_counter = 1
|
||||
local function add_index(page, r)
|
||||
index_map[page] = {page_num = details_index_counter, res = r}
|
||||
details_index_counter = details_index_counter + 1
|
||||
if res == nil then
|
||||
res = r
|
||||
end
|
||||
end
|
||||
|
||||
local function preshow()
|
||||
local cati_current = 0
|
||||
if show_artifacts then
|
||||
cati_current = cati_current + 1
|
||||
wesnoth.add_dialog_tree_node("category", cati_current, "left_tree")
|
||||
wesnoth.set_dialog_value(true, "left_tree", cati_current)
|
||||
wesnoth.set_dialog_value(_ "Artifacts", "left_tree", cati_current, "category_name")
|
||||
for i,v in ipairs(available_artifacts) do
|
||||
local artifact_info = wc2_artifacts.get_artifact(tonumber(v))
|
||||
if not artifact_info then
|
||||
error("invalid item id'" .. v .. "'")
|
||||
end
|
||||
wesnoth.add_dialog_tree_node("item_desc", i, "left_tree", cati_current)
|
||||
wesnoth.set_dialog_value(artifact_info.icon, "left_tree", cati_current, i, "image")
|
||||
wesnoth.set_dialog_value(artifact_info.name, "left_tree", cati_current, i, "name")
|
||||
wesnoth.set_dialog_value(wc2_color.tc_text(artifact_info.description), "left_tree", cati_current, i, "desc")
|
||||
|
||||
wesnoth.add_dialog_tree_node("", -1, "details")
|
||||
wesnoth.set_dialog_value(artifact_info.info, "details", details_index_counter, "label")
|
||||
add_index(cati_current .. "_" .. i, { pick = "item", type=v })
|
||||
end
|
||||
end
|
||||
|
||||
if show_heroes then
|
||||
cati_current = cati_current + 1
|
||||
wesnoth.add_dialog_tree_node("category", cati_current, "left_tree")
|
||||
wesnoth.set_dialog_value(true, "left_tree", cati_current)
|
||||
wesnoth.set_dialog_value(_ "Heroes", "left_tree", cati_current, "category_name")
|
||||
local i = 1
|
||||
if available_commanders then
|
||||
local desc = _ "Commanders will take your leaders place when the leader dies, possible commanders:"
|
||||
for j,v in ipairs(available_commanders) do
|
||||
desc = desc .. "\n" .. wesnoth.unit_types[v].name
|
||||
end
|
||||
|
||||
wesnoth.add_dialog_tree_node("item", i, "left_tree", cati_current)
|
||||
wesnoth.set_dialog_value(wc2_color.tc_image("units/unknown-unit.png"), "left_tree", cati_current, i, "image")
|
||||
wesnoth.set_dialog_value(_ "Commander" .. "\n" .. wc2_color.tc_text(_ "promote to leader"), "left_tree", cati_current, i, "name")
|
||||
|
||||
wesnoth.add_dialog_tree_node("", -1, "details")
|
||||
wesnoth.set_dialog_value(desc, "details", details_index_counter, "label")
|
||||
add_index(cati_current .. "_" .. i, { pick = "hero", type="wc2_commander" })
|
||||
i = i + 1
|
||||
end
|
||||
for j,v in ipairs(available_heroes) do
|
||||
unit_type = wesnoth.unit_types[v]
|
||||
|
||||
wesnoth.add_dialog_tree_node("item", i, "left_tree", cati_current)
|
||||
wesnoth.set_dialog_value(wc2_color.tc_image(unit_type.image), "left_tree", cati_current, i, "image")
|
||||
wesnoth.set_dialog_value(unit_type.name, "left_tree", cati_current, i, "name")
|
||||
|
||||
wesnoth.add_dialog_tree_node("hero", -1, "details")
|
||||
wesnoth.set_dialog_value(unit_type, "details", details_index_counter, "unit")
|
||||
add_index(cati_current .. "_" .. i, { pick = "hero", type=v })
|
||||
i = i + 1
|
||||
end
|
||||
if available_deserters then
|
||||
local desc = "<b>" .. _ "possible units:" .. "</b>"
|
||||
for j,v in ipairs(available_deserters) do
|
||||
desc = desc .. "\n" .. wesnoth.unit_types[v].name
|
||||
end
|
||||
wesnoth.add_dialog_tree_node("item", i, "left_tree", cati_current)
|
||||
wesnoth.set_dialog_value(wc2_color.tc_image("units/unknown-unit.png"), "left_tree", cati_current, i, "image")
|
||||
wesnoth.set_dialog_value(_ "Deserter" .. "\n" .. wc2_color.tc_text("+15 gold"), "left_tree", cati_current, i, "name")
|
||||
|
||||
wesnoth.add_dialog_tree_node("", -1, "details")
|
||||
wesnoth.set_dialog_value(desc, "details", details_index_counter, "label")
|
||||
add_index(cati_current .. "_" .. i, { pick = "hero", type="wc2_deserter" })
|
||||
end
|
||||
end
|
||||
|
||||
if show_training then
|
||||
cati_current = cati_current + 1
|
||||
wesnoth.add_dialog_tree_node("category", cati_current, "left_tree")
|
||||
wesnoth.set_dialog_value(true, "left_tree", cati_current)
|
||||
wesnoth.set_dialog_value(_ "Training", "left_tree", cati_current, "category_name")
|
||||
for i,v in ipairs(available_training) do
|
||||
local current_grade = wc2_training.get_level(side_num, v)
|
||||
local training_info = wc2_training.get_trainer(v)
|
||||
local train_message = wc2_training.generate_message(v, current_grade + 1)
|
||||
local train_message_before = wc2_training.generate_message(v, current_grade)
|
||||
|
||||
local title = wesnoth.format(_ "$name Training", { name = training_info.name })
|
||||
local desc = wc2_training.describe_training_level2(current_grade, #training_info.grade) .. wc2_color.tc_text(" → ") .. wc2_training.describe_training_level2(current_grade + 1, #training_info.grade)
|
||||
|
||||
wesnoth.add_dialog_tree_node("item_desc", i, "left_tree", cati_current)
|
||||
wesnoth.set_dialog_value(training_info.image, "left_tree", cati_current, i, "image")
|
||||
wesnoth.set_dialog_value(title, "left_tree", cati_current, i, "name")
|
||||
wesnoth.set_dialog_value(desc, "left_tree", cati_current, i, "desc")
|
||||
|
||||
wesnoth.add_dialog_tree_node("", -1, "details")
|
||||
local label = wc2_color.tc_text("<big>" .. _ "Before:" .. "</big>\n") .. train_message_before.message .. wc2_color.tc_text("\n<big>" .. _ "After:" .. "</big>\n") .. train_message.message
|
||||
wesnoth.set_dialog_value(label , "details", details_index_counter, "label")
|
||||
--wesnoth.set_dialog_value(train_message.message, "details", details_index_counter, "training_after")
|
||||
add_index(cati_current .. "_" .. i, { pick = "training", type=v })
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
if show_other then
|
||||
cati_current = cati_current + 1
|
||||
wesnoth.add_dialog_tree_node("category", cati_current, "left_tree")
|
||||
wesnoth.set_dialog_value(true, "left_tree", cati_current)
|
||||
wesnoth.set_dialog_value(_ "Other", "left_tree", cati_current, "category_name")
|
||||
|
||||
|
||||
|
||||
local colored_galleon = wc2_color.tc_image("units/transport/transport-galleon.png")
|
||||
local supplies_image = "misc/blank-hex.png~SCALE(90,80)~BLIT(" .. colored_galleon .. ",9,4)"
|
||||
local supplies_text = wc2_color.tc_text(_ "+70 gold and +1 village")
|
||||
--"+{STR_COLOR_PLAYER ("+70 "+{STR_GOLD}+{STR_AND}+"+1 "+{STR_VILLAGE})}
|
||||
|
||||
wesnoth.add_dialog_tree_node("item_desc", 1, "left_tree", cati_current)
|
||||
wesnoth.set_dialog_value(supplies_image, "left_tree", cati_current, 1, "image")
|
||||
wesnoth.set_dialog_value(_"Stock up supplies", "left_tree", cati_current, 1, "name")
|
||||
wesnoth.set_dialog_value(supplies_text, "left_tree", cati_current, 1, "desc")
|
||||
|
||||
wesnoth.add_dialog_tree_node("", -1, "details")
|
||||
wesnoth.set_dialog_value(_"Gives 70 gold and places a village on your keep.", "details", details_index_counter, "label")
|
||||
add_index(cati_current .. "_" .. 1, { pick = "gold" })
|
||||
end
|
||||
|
||||
wesnoth.set_dialog_callback(function()
|
||||
local selected = wesnoth.get_dialog_value("left_tree")
|
||||
local selected_data = index_map[table.concat(selected, '_')]
|
||||
if selected_data ~= nil then
|
||||
wesnoth.set_dialog_value(selected_data.page_num, "details")
|
||||
end
|
||||
res = selected_data.res
|
||||
end, "left_tree")
|
||||
end
|
||||
local d_res = wesnoth.show_dialog(dialog_wml, preshow)
|
||||
return d_res, res
|
||||
end
|
||||
|
||||
function wc2_show_invest_dialog(args)
|
||||
--do it in a loop to disable esc.
|
||||
while true do
|
||||
local d_res, res = wc2_show_invest_dialog_impl(args)
|
||||
if d_res ~= -2 then
|
||||
return res
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return wc2_show_invest_dialog
|
|
@ -0,0 +1,72 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local T = wml.tag
|
||||
|
||||
local invest_tellunit = {}
|
||||
|
||||
invest_tellunit.dialog_wml = {
|
||||
maximum_width = 1200,
|
||||
maximum_height = 700,
|
||||
T.helptip { id = "tooltip_large" }, -- mandatory field
|
||||
T.tooltip { id = "tooltip_large" }, -- mandatory field
|
||||
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
border = "all",
|
||||
border_size = 5,
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
definition = "title",
|
||||
label = _"You got",
|
||||
id = "title"
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
T.image {
|
||||
id="icon"
|
||||
}
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
T.label {
|
||||
id="name"
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
T.button {
|
||||
label = _"Ok",
|
||||
id = "ok",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- todo:maybe use a dialog ith the unit specific welcome mesage?
|
||||
function invest_tellunit.execute(unit_type)
|
||||
if type(unit_type) == "string" then
|
||||
unit_type = wesnoth.unit_types[unit_type]
|
||||
end
|
||||
if not wesnoth.sides[wesnoth.current.side].is_local then
|
||||
return
|
||||
end
|
||||
local function preshow()
|
||||
wesnoth.set_dialog_value(wc2_color.tc_image(unit_type.image), "icon")
|
||||
wesnoth.set_dialog_value(unit_type.name, "name")
|
||||
end
|
||||
|
||||
wesnoth.show_dialog(invest_tellunit.dialog_wml, preshow)
|
||||
end
|
||||
|
||||
return invest_tellunit
|
|
@ -0,0 +1,98 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local T = wml.tag
|
||||
|
||||
local pickup_confirmation_dialog = {}
|
||||
|
||||
-- returns true when the item should be picked up.
|
||||
local function show_dialog(unit, item_image)
|
||||
if wc2_utils.global_vars.skip_pickup_dialog then
|
||||
return 1
|
||||
end
|
||||
|
||||
local dialog_wml = {
|
||||
maximum_width = 1200,
|
||||
maximum_height = 700,
|
||||
T.helptip { id = "tooltip_large" }, -- mandatory field
|
||||
T.tooltip { id = "tooltip_large" }, -- mandatory field
|
||||
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
border = "all",
|
||||
border_size = 5,
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
definition = "title",
|
||||
label = _"Pick up item?",
|
||||
id = "title",
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
T.image {
|
||||
id="item_icon",
|
||||
},
|
||||
},
|
||||
T.column {
|
||||
T.label {
|
||||
id="arrow",
|
||||
use_markup=true
|
||||
},
|
||||
},
|
||||
T.column {
|
||||
T.image {
|
||||
id="unit_icon",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
T.button {
|
||||
label = _"Yes (enter)",
|
||||
id="res_yes",
|
||||
return_value = 1,
|
||||
},
|
||||
},
|
||||
T.column {
|
||||
T.button {
|
||||
label = _"No (esc)",
|
||||
id="res_no",
|
||||
return_value = 2
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
local function preshow()
|
||||
wesnoth.set_dialog_value(wc2_color.tc_image(wesnoth.unit_types[unit.type].image), "unit_icon")
|
||||
wesnoth.set_dialog_value(wc2_color.tc_text(" → "), "arrow")
|
||||
wesnoth.set_dialog_value(item_image, "item_icon")
|
||||
wesnoth.set_dialog_focus("res_yes")
|
||||
end
|
||||
local res = wesnoth.show_dialog(dialog_wml, preshow)
|
||||
return res == 1 or res == -1
|
||||
end
|
||||
|
||||
-- returns true when the item should be picked up.
|
||||
function pickup_confirmation_dialog.promt_synced(unit, item_image)
|
||||
local res = wesnoth.synchronize_choice("Item Pickup Choice", function()
|
||||
return { take_item = show_dialog(unit, item_image) }
|
||||
end)
|
||||
return res.take_item
|
||||
end
|
||||
|
||||
return pickup_confirmation_dialog
|
|
@ -0,0 +1,39 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local on_event = wesnoth.require("on_event")
|
||||
|
||||
local strings = {
|
||||
defeat = _ "No! This is the end!",
|
||||
promotion = _ "Don't lose heart comrades, we can still win this battle."
|
||||
}
|
||||
|
||||
-- when a leader dies, take a commonder and make him the leader.
|
||||
on_event("die", function(cx)
|
||||
local u = wesnoth.get_unit(cx.x1, cx.y1)
|
||||
if (not u) or (not u:matches({ canrecruit = true })) then
|
||||
return
|
||||
end
|
||||
local commander = wesnoth.get_units {
|
||||
side = u.side,
|
||||
role = "commander",
|
||||
canrecruit = false
|
||||
}
|
||||
commander = commander[1]
|
||||
if commander then
|
||||
commander.canrecruit = true
|
||||
commander:remove_modifications({ id = "wc2_commander_overlay" })
|
||||
wesnoth.wml_actions.message {
|
||||
id = commander.id,
|
||||
message = strings.promotion
|
||||
}
|
||||
else
|
||||
if u.side < 4 then
|
||||
wesnoth.wml_actions.message {
|
||||
side = "1,2,3",
|
||||
message = strings.defeat
|
||||
}
|
||||
wesnoth.wml_actions.endlevel {
|
||||
result = "defeat"
|
||||
}
|
||||
end
|
||||
end
|
||||
end)
|
17
data/campaigns/World_Conquest/lua/game_mechanics/recall.lua
Normal file
|
@ -0,0 +1,17 @@
|
|||
local function add_rc_object(u)
|
||||
if not u.variables.wc2_has_recall_object then
|
||||
u.variables.wc2_has_recall_object = true
|
||||
u:add_modification("object", {
|
||||
{"effect", {
|
||||
apply_to = "wc2_recall_cost"
|
||||
}},
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- the implementation of the addons reduces recall cost mechanic.
|
||||
function wesnoth.wml_actions.wc2_set_recall_cost(cfg)
|
||||
for i,u in ipairs(wesnoth.get_units { side = "1,2,3" }) do
|
||||
add_rc_object(u)
|
||||
end
|
||||
end
|
32
data/campaigns/World_Conquest/lua/game_mechanics/supply.lua
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
local supply_images =
|
||||
{
|
||||
"misc/blank-hex.png~BLIT(items/straw-bale2.png~CROP(24,15,48,57))~BLIT(items/straw-bale1.png~CROP(0,9,72,63))",
|
||||
"misc/blank-hex.png~BLIT(items/straw-bale1.png~CROP(8,15,64,57))~BLIT(items/leather-pack.png~CROP(0,10,62,62),10,0)~BLIT(items/leather-pack.png~CROP(0,0,69,72),3,0)",
|
||||
"misc/blank-hex.png~BLIT(items/straw-bale2.png~CROP(19,18,53,54))~BLIT(items/straw-bale2.png~CROP(7,6,65,66))~BLIT(items/leather-pack.png~CROP(4,23,68,49))~BLIT(items/straw-bale2.png~CROP(7,15,65,57))",
|
||||
-- custom image
|
||||
"terrain/wct-supply2.png",
|
||||
-- custom image
|
||||
"terrain/wct-supply1.png",
|
||||
"misc/blank-hex.png~BLIT(items/box.png~SCALE(54,54)~CROP(0,11,54,43),4,0)~BLIT(items/straw-bale2.png~CROP(5,24,67,48),0,24)~BLIT(items/leather-pack.png~CROP(0,9,63,63),9,0)",
|
||||
"misc/blank-hex.png~BLIT(items/box.png~SCALE(54,54)~CROP(0,11,54,43),4,0)~BLIT(items/box.png~SCALE(54,54)~CROP(0,1,54,53),17,0)",
|
||||
-- custom image
|
||||
"terrain/wct-supply3.png~BLIT(items/box.png~SCALE(54,54)~CROP(0,1,54,53),17,0)",
|
||||
}
|
||||
|
||||
function wesnoth.wml_actions.wc2_map_supply_village(t)
|
||||
local unit = wesnoth.get_unit(t.x, t.y)
|
||||
local loc = unit.loc
|
||||
wesnoth.set_terrain(loc, "Kh^Vov", "overlay")
|
||||
|
||||
wesnoth.set_village_owner(loc, unit.side, false)
|
||||
|
||||
local supply_image = ((wml.variables.wc2_supply_image_counter or 0) % #supply_images ) + 1
|
||||
wml.variables.wc2_supply_image_counter = supply_image
|
||||
wesnoth.wml_actions.item {
|
||||
x = loc[1],
|
||||
y = loc[2],
|
||||
image = supply_images[supply_image],
|
||||
z_order = -10,
|
||||
}
|
||||
end
|
284
data/campaigns/World_Conquest/lua/game_mechanics/training.lua
Normal file
|
@ -0,0 +1,284 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local on_event = wesnoth.require("on_event")
|
||||
local helper = wesnoth.require("helper")
|
||||
|
||||
|
||||
local training = {}
|
||||
|
||||
|
||||
function training.add_training_data(a)
|
||||
training.trainers = training.trainers or {}
|
||||
table.insert(training.trainers, a)
|
||||
end
|
||||
|
||||
function training.read_wml_data(cfg)
|
||||
for i, t in ipairs(wc2_convert.wml_to_lon(cfg, "wct_trainer_list").trainer or {}) do
|
||||
training.add_training_data(t)
|
||||
end
|
||||
end
|
||||
|
||||
function training.get_list()
|
||||
if not training.trainers then
|
||||
training.init_data()
|
||||
end
|
||||
return training.trainers
|
||||
end
|
||||
|
||||
function training.init_data()
|
||||
local cfg = wc2_utils.get_wc2_data("trainer")
|
||||
for i, t in ipairs(wc2_convert.wml_to_lon(cfg, "wct_trainer_list").trainer or {}) do
|
||||
training.add_training_data(t)
|
||||
end
|
||||
end
|
||||
|
||||
function training.get_trainer(trainer)
|
||||
return training.get_list()[trainer]
|
||||
end
|
||||
|
||||
|
||||
function training.get_chances(trainer, grade)
|
||||
return training.get_trainer(trainer).grade[grade + 1].chance
|
||||
end
|
||||
|
||||
function training.apply_trait(unit, trait, check)
|
||||
if u:matches(check) and u:matches( wml.tag.filter_wml { wml.tag.modifications { wml.tag.trait { id = trait.id } } } ) then
|
||||
u:add_modification("trait", trait)
|
||||
else
|
||||
u:add_modification("object", { wml.tag.effect { apply_to = "hitpoints", increase_total = 1, heal_full = true}})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--the current level of a certain traing, a value of 0 means this skill wasn't trained yet.
|
||||
function training.get_level(side_num, trainer)
|
||||
return wesnoth.sides[side_num].variables["wc2.training[" .. trainer - 1 .. "].level"] or 0
|
||||
end
|
||||
|
||||
function training.set_level(side_num, trainer, level)
|
||||
wesnoth.sides[side_num].variables["wc2.training[" .. trainer - 1 .. "].level"] = level
|
||||
end
|
||||
|
||||
function training.inc_level(side, trainer, level)
|
||||
local new_level = training.get_level(side, trainer) + (level or 1)
|
||||
if new_level < 0 or new_level >= #training.get_trainer(trainer).grade then
|
||||
error("training level out of range")
|
||||
end
|
||||
training.set_level(side, trainer, new_level)
|
||||
end
|
||||
|
||||
-- to be used by bonus points chance to extra taining.
|
||||
function training.get_level_sum(side)
|
||||
local res = 0
|
||||
for i = 1, #training.get_list() do
|
||||
res = res + training.get_level(side, i)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function training.trainings_left(side_num, trainer)
|
||||
return (#training.get_trainer(trainer).grade - 1) - training.get_level(side_num, trainer)
|
||||
end
|
||||
|
||||
function training.available(side_num, trainer, amount)
|
||||
return training.trainings_left(side_num, trainer) >= (amount or 1)
|
||||
end
|
||||
|
||||
function training.has_max_training(side_num, trainer, amount)
|
||||
return training.available(side_num, trainer) == 0
|
||||
end
|
||||
|
||||
function training.list_available(side_num, among, amount)
|
||||
local av = among or wc2_utils.range(#training.get_list())
|
||||
local res = {}
|
||||
for i,v in ipairs(av) do
|
||||
local j = tonumber(v)
|
||||
if training.available(side_num, j, amount) then
|
||||
table.insert(res, j)
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function training.find_available(side_num, among, amount)
|
||||
local possible_traintypes = training.list_available(side_num, among, amount)
|
||||
if #possible_traintypes == 0 then
|
||||
return
|
||||
else
|
||||
return possible_traintypes[wesnoth.random(#possible_traintypes)]
|
||||
end
|
||||
end
|
||||
|
||||
function training.describe_training_level(name, level, max_level)
|
||||
if level == max_level then
|
||||
return tostring(wesnoth.format(_ "$name Training Maximum Level", {
|
||||
name = name
|
||||
}))
|
||||
else
|
||||
return tostring(wesnoth.format(_ "$name Training level $level", {
|
||||
name = name,
|
||||
level = level
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
function training.describe_training_level2(level, max_level)
|
||||
if level == max_level then
|
||||
return _ "Maximum Level"
|
||||
else
|
||||
return tostring(wesnoth.format(_ "level $level", {
|
||||
level = level
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
function training.generate_message(n_trainer, n_grade)
|
||||
local c_trainer = training.get_trainer(n_trainer)
|
||||
local c_grade = c_trainer.grade[n_grade + 1]
|
||||
if c_grade == nil then
|
||||
return { message = "" }
|
||||
end
|
||||
local caption = training.describe_training_level(c_trainer.name, n_grade, #c_trainer.grade - 1)
|
||||
local messages = {}
|
||||
for unused, chance in ipairs(c_grade.chance) do
|
||||
local vchance = chance.variable_substitution ~= false and wesnoth.tovconfig(chance) or chance
|
||||
if (chance.value or 0) < 100 then
|
||||
local str = wesnoth.format(_ "$chance| chance to $arrow $desc", {
|
||||
chance = ("%d%%"):format(vchance.value),
|
||||
desc = wc2_utils.get_fstring(chance, "info"),
|
||||
arrow = wc2_color.tc_text(" → ")
|
||||
})
|
||||
table.insert(messages, tostring(str))
|
||||
else
|
||||
table.insert(messages, tostring(wc2_utils.get_fstring(chance, "info")))
|
||||
end
|
||||
end
|
||||
return {
|
||||
caption = caption,
|
||||
message = table.concat(messages, "\n"),
|
||||
speaker = "narrator",
|
||||
image = c_trainer.image,
|
||||
}
|
||||
end
|
||||
|
||||
function training.give_bonus(side_num, cx, amount, traintype_index)
|
||||
local traintype = training.get_trainer(traintype_index)
|
||||
local cur_level = training.get_level(side_num, traintype_index)
|
||||
local new_level = cur_level + amount
|
||||
local teacher = wc2_heroes.place(amount > 1 and traintype.advanced_type or traintype.type, side_num, cx.x1,cx.y1)
|
||||
local u = wesnoth.get_unit(cx.x1, cx.y1)
|
||||
wc2_utils.facing_each_other(u, teacher)
|
||||
|
||||
wesnoth.wml_actions.sound {
|
||||
name = "flail-miss.ogg"
|
||||
}
|
||||
wesnoth.wml_actions.message {
|
||||
speaker = teacher.id,
|
||||
message = traintype.dialogue,
|
||||
}
|
||||
wesnoth.extract_unit(teacher)
|
||||
local message = training.generate_message(traintype_index, new_level)
|
||||
wesnoth.wml_actions.message(message)
|
||||
|
||||
training.inc_level(side_num, traintype_index, amount)
|
||||
return true
|
||||
end
|
||||
|
||||
function training.bonus_calculate_amount(side_num)
|
||||
local amount = 1
|
||||
local advanced_chance = 4 * training.get_level_sum(side_num)
|
||||
if wc2_scenario.scenario_num() > 3 or wesnoth.random(100) <= advanced_chance then
|
||||
amount = 2
|
||||
end
|
||||
return amount
|
||||
end
|
||||
|
||||
function training.pick_bonus(side_num)
|
||||
local amount = training.bonus_calculate_amount(side_num)
|
||||
-- dark training reduced chances
|
||||
local traintype_index = training.find_available(side_num, {1,2,3,4,5,6,2,3,4,5,6,2,3,4,5,6}, amount)
|
||||
if traintype_index == nil then
|
||||
return nil
|
||||
end
|
||||
|
||||
--dark training increased level.
|
||||
if traintype_index == 1 then
|
||||
amount = math.min(training.trainings_left(side_num, traintype_index), math.max(amount, wc2_scenario.scenario_num() - 1))
|
||||
end
|
||||
return traintype_index, amount
|
||||
end
|
||||
|
||||
on_event("recruit", function(event_context)
|
||||
training.apply(wesnoth.get_unit(event_context.x1, event_context.y1))
|
||||
end)
|
||||
|
||||
function training.apply(u)
|
||||
if not u then
|
||||
return
|
||||
end
|
||||
local side = u.side
|
||||
local trait = {}
|
||||
local descriptions = {}
|
||||
trait.male_name = _ "trained"
|
||||
trait.female_name = _ "female^trained"
|
||||
trait.generate_description = false
|
||||
for i, trainer in ipairs(training.get_list()) do
|
||||
local level = training.get_level(side, i) or 0
|
||||
for unused, chance in ipairs(training.get_chances(i, level)) do
|
||||
--some effects use expressions like $(5+{GRADE}) so we want variable_substitution there
|
||||
local vchance = wesnoth.tovconfig(chance)
|
||||
local filter = wml.get_child(vchance, "filter")
|
||||
local matches_filter = (not filter) or u:matches(filter)
|
||||
if wesnoth.random(100) <= vchance.value and matches_filter then
|
||||
--wesnoth.wml_actions.message { message = "Got it" }
|
||||
table.insert(descriptions, wc2_utils.get_fstring(chance, "info"))
|
||||
for effect in helper.child_range(vchance, "effect") do
|
||||
table.insert(trait, {"effect", effect })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
trait.description = wc2_utils.concat(descriptions, "\n")
|
||||
if #trait > 0 then
|
||||
u:add_modification("trait", trait)
|
||||
--rebuild unit, to reduce savefile size.
|
||||
u:transform(u.type)
|
||||
end
|
||||
u.variables.wc2_trained = true
|
||||
u.hitpoints = u.max_hitpoints
|
||||
end
|
||||
|
||||
function wesnoth.wml_actions.wc2_apply_training(cfg)
|
||||
for i,u in ipairs(wesnoth.get_units(cfg)) do
|
||||
training.apply(u)
|
||||
end
|
||||
end
|
||||
|
||||
function wesnoth.wml_actions.wc2_give_random_training(cfg)
|
||||
local side_num = cfg.side
|
||||
local amount = cfg.amount or 1
|
||||
local among = cfg.among and wc2_utils.split_to_array(cfg.among)
|
||||
for i = 1, amount do
|
||||
local traintype = training.find_available(side_num, among)
|
||||
if traintype == nil then error("wc2_give_random_training: everything alerady maxed") end
|
||||
training.inc_level(side_num, traintype, 1)
|
||||
end
|
||||
end
|
||||
|
||||
function training.describe_bonus(side, traintype)
|
||||
local traintype_data = training.get_trainer(traintype)
|
||||
local cur_level = training.get_level(side, traintype)
|
||||
local max_level = #traintype_data.grade - 1
|
||||
local image = wesnoth.unit_types[traintype_data.type].__cfg.image
|
||||
local message = nil
|
||||
if cur_level == max_level then
|
||||
message = _"Nothing to learn here"
|
||||
else
|
||||
message = wesnoth.format(_"From $level_before to $level_after", {
|
||||
level_before = training.describe_training_level(traintype_data.name, cur_level, max_level),
|
||||
level_after = training.describe_training_level(traintype_data.name, cur_level + 1, max_level)
|
||||
})
|
||||
end
|
||||
return message, image
|
||||
end
|
||||
|
||||
return training
|
|
@ -0,0 +1,404 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
|
||||
type_infos = {
|
||||
["default"] = {
|
||||
founddialogue = _"You guys look like you could use some help. Mind if I join in? It's been a while since I had a good fight!",
|
||||
reply = _ "Excellent. We could always use more help.",
|
||||
},
|
||||
["Orcish Grunt"] = {
|
||||
founddialogue=_"'bout time. Been forever since I had a good fight, eh?",
|
||||
image="units/orcs/grunt.png",
|
||||
name="Orcish Grunt",
|
||||
},
|
||||
["Troll Whelp"] = {
|
||||
founddialogue=_"Who you? I help you smash!",
|
||||
image="units/trolls/whelp.png",
|
||||
name="Troll Whelp",
|
||||
},
|
||||
["Orcish Archer"] = {
|
||||
founddialogue=_"My clan was destroyed long ago, leaving me to fend for myself. Let me join your army and I will fight as though your clan was my own!",
|
||||
image="units/orcs/archer.png",
|
||||
name="Orcish Archer",
|
||||
},
|
||||
["Orcish Assassin"] = {
|
||||
founddialogue=_"Heya, boss. Looks like you've got some guys need killing.",
|
||||
image="units/orcs/assassin.png",
|
||||
name="Orcish Assassin",
|
||||
},
|
||||
["Wolf Rider"] = {
|
||||
founddialogue=_"I hunts. I join you, I hunts good for you!",
|
||||
image="units/goblins/wolf-rider.png",
|
||||
name="Wolf Rider",
|
||||
alt_reply = { {
|
||||
race="wose",
|
||||
reply=_"Ok. But take care where your dog does its stuff.",
|
||||
} }
|
||||
},
|
||||
["Orcish Leader"] = {
|
||||
founddialogue=_"Heh, looks like you whelps might be getting in over your heads. Good thing I'm here now to win this fight for ya, huh?",
|
||||
image="units/orcs/leader.png",
|
||||
name="Orcish Leader",
|
||||
},
|
||||
["Naga Fighter"] = {
|
||||
founddialogue=_"I too have come a long way to this strange land. Perhaps we were destined to join blades here.",
|
||||
image="units/nagas/fighter.png",
|
||||
name="Naga Fighter",
|
||||
alt_reply = { {
|
||||
race="gryphon",
|
||||
reply=_"Looks like we fished some tasty help.",
|
||||
} }
|
||||
},
|
||||
["Mage"] = {
|
||||
image="units/human-magi/mage.png",
|
||||
name="Mage",
|
||||
},
|
||||
["Elvish Fighter"] = {
|
||||
founddialogue=_"Need a friendly blade?",
|
||||
image="units/elves-wood/fighter.png",
|
||||
name="Elvish Fighter",
|
||||
},
|
||||
["Elvish Archer"] = {
|
||||
founddialogue=_"You guys look like you could use some help. Mind if I join in? It's been a while since I had a good fight!",
|
||||
image="units/elves-wood/archer.png",
|
||||
name="Elvish Archer",
|
||||
},
|
||||
["Elvish Shaman"] = {
|
||||
founddialogue=_"The mother forest sends you her blessings. Let us join together against her foes.",
|
||||
image="units/elves-wood/shaman.png",
|
||||
name="Elvish Shaman",
|
||||
alt_reply = { {
|
||||
race="elf,wose",
|
||||
reply=_"Yea, flower power!",
|
||||
} }
|
||||
},
|
||||
["Elvish Scout"] = {
|
||||
founddialogue=_"I offer you the service of my arrows and my steed. You will find none that fly faster than either.",
|
||||
image="units/elves-wood/scout/scout.png",
|
||||
name="Elvish Scout",
|
||||
},
|
||||
["Wose"] = {
|
||||
founddialogue=_"Hmm! Welcome, tree-friends. We will pound our enemies into dust!",
|
||||
image="units/woses/wose.png",
|
||||
name="Wose",
|
||||
},
|
||||
["Merman Hunter"] = {
|
||||
founddialogue=_"Greetings, friends. I am a lone hunter and have no legions of warriors to offer you, but I will gladly lend my arms to your cause.",
|
||||
image="units/merfolk/hunter.png",
|
||||
name="Merman Hunter",
|
||||
alt_reply = { {
|
||||
race="gryphon",
|
||||
reply=_"Looks like we fished some tasty help.",
|
||||
} }
|
||||
},
|
||||
["Mermaid Initiate"] = {
|
||||
founddialogue=_"You have come a long way over the ocean, yet I see that you know little of her ways. Let me show you.",
|
||||
image="units/merfolk/initiate.png",
|
||||
name="Mermaid Initiate",
|
||||
alt_reply = { {
|
||||
race="gryphon",
|
||||
reply=_"Looks like we fished some tasty help.",
|
||||
} }
|
||||
},
|
||||
["Cavalryman"] = {
|
||||
founddialogue=_"You're not from around here, but I seem to find myself between employers at the moment and I'm not picky. I'll fight for you, if you'll have me.",
|
||||
image="units/human-loyalists/cavalryman/cavalryman.png~CROP(14,14,72,72)",
|
||||
name="Cavalryman",
|
||||
alt_reply = { {
|
||||
gender="female",
|
||||
reply=_"Of course. How could a girl say no to a man riding a horse?",
|
||||
} }
|
||||
},
|
||||
["Horseman"] = {
|
||||
founddialogue=_"Hurrah! Now THIS is a battle too grand to be missed. Save some for me, eh?",
|
||||
image="units/human-loyalists/horseman/horseman.png",
|
||||
name="Horseman",
|
||||
alt_reply = { {
|
||||
gender="female",
|
||||
reply=_"Of course. How could a girl say no to a man riding a horse?",
|
||||
} }
|
||||
},
|
||||
["Spearman"] = {
|
||||
founddialogue=_"Ho there, friends! I am but a soldier of humble circumstances, yet long have I dreamed of joining great wars beyond our shores. Let me join your mission!",
|
||||
image="units/human-loyalists/spearman.png",
|
||||
name="Spearman",
|
||||
},
|
||||
["Fencer"] = {
|
||||
founddialogue=_"Looks like you're a bit down on your luck, my friends. But now that I am here, there's nothing to worry about!",
|
||||
image="units/human-loyalists/fencer.png",
|
||||
name="Fencer",
|
||||
},
|
||||
["Heavy Infantryman"] = {
|
||||
founddialogue=_"Finally reinforcements are here! I've been pinned down for days. Help me fight my way out of here and I'll gladly follow you!",
|
||||
image="units/human-loyalists/heavyinfantry.png",
|
||||
name="Heavy Infantryman",
|
||||
},
|
||||
["Bowman"] = {
|
||||
founddialogue=_"Greetings, my lords. I have watched your battle from afar and yearn to join such a glorious campaign. I pledge myself to your service!",
|
||||
image="units/human-loyalists/bowman.png",
|
||||
name="Bowman",
|
||||
},
|
||||
["Sergeant"] = {
|
||||
founddialogue=_"You're not from around here, but I seem to find myself between employers at the moment and I'm not picky. I'll fight for you, if you'll have me.",
|
||||
image="units/human-loyalists/sergeant.png",
|
||||
name="Sergeant",
|
||||
},
|
||||
["Mage"] = {
|
||||
founddialogue=_"Long have I studied the ways of lore, and I have much wisdom to offer. Allow me to guide you on your quest and together we will accomplish great things!",
|
||||
image="units/human-magi/mage.png",
|
||||
name="Mage",
|
||||
},
|
||||
["Merman Fighter"] = {
|
||||
founddialogue=_"I bring greetings from the merfolk. We have heard your plight, and though we have few warriors to spare among us, I would gladly lend my trident to your cause.",
|
||||
image="units/merfolk/fighter.png",
|
||||
name="Merman Fighter",
|
||||
alt_reply = { {
|
||||
race="gryphon",
|
||||
reply=_"Looks like we fished some tasty help.",
|
||||
} }
|
||||
},
|
||||
["Dwarvish Fighter"] = {
|
||||
founddialogue=_"Having trouble, eh? Never worry, lads, we'll sort 'em out soon enough!",
|
||||
image="units/dwarves/fighter.png",
|
||||
name="Dwarvish Fighter",
|
||||
},
|
||||
["Thief"] = {
|
||||
founddialogue=_"You've got me, guv, it's a fair cop! Just lemme work for you instead. You won't regret it, guv, I promise!",
|
||||
image="units/human-outlaws/thief.png",
|
||||
name="Thief",
|
||||
},
|
||||
["Dwarvish Thunderer"] = {
|
||||
founddialogue=_"Listen up, ye primitive screwheads! This... is me BOOM STICK. Lemme show you what this baby can do!",
|
||||
image="units/dwarves/thunderer/thunderer.png",
|
||||
name="Dwarvish Thunderer",
|
||||
},
|
||||
["Poacher"] = {
|
||||
founddialogue=_"What, you want my help? A guy like me? Huh, that's rich. Oh well... let's give it a shot, eh?",
|
||||
image="units/human-outlaws/poacher.png",
|
||||
name="Poacher",
|
||||
},
|
||||
["Dwarvish Guardsman"] = {
|
||||
founddialogue=_"A soldier is no good without something to fight for. Let me fight for you!",
|
||||
image="units/dwarves/guard.png",
|
||||
name="Dwarvish Guardsman",
|
||||
},
|
||||
["Footpad"] = {
|
||||
founddialogue=_"Hey, hey, easy there! I done nothin' to hurt you. We're all friends here, right? Looks like you might be in a tight spot, but don't worry. No one's better at getting out of tight spots than me, boss!",
|
||||
image="units/human-outlaws/footpad.png",
|
||||
name="Footpad",
|
||||
},
|
||||
["Dwarvish Ulfserker"] = {
|
||||
founddialogue=_"Chin up, lads. Today is a good day to die!",
|
||||
image="units/dwarves/ulfserker.png",
|
||||
name="Dwarvish Ulfserker",
|
||||
alt_reply = { {
|
||||
race="dwarf",
|
||||
reply=_"Brave words. Welcome to The Fight Club...",
|
||||
}, {
|
||||
race="human",
|
||||
reply=_"Brave words. Welcome little big man.",
|
||||
} }
|
||||
},
|
||||
["Gryphon Rider"] = {
|
||||
founddialogue=_"Need a hand? Me an' me bird can get just about anywheres you need.",
|
||||
image="units/dwarves/gryphon-rider.png",
|
||||
name="Gryphon Rider",
|
||||
alt_reply = { {
|
||||
race="merman,naga",
|
||||
reply=_"Sounds good. You scared me for a moment.",
|
||||
}, {
|
||||
race="gryphon,bats",
|
||||
reply=_"Cool. We could always need more air power.",
|
||||
} }
|
||||
},
|
||||
["Dwarvish Scout"] = {
|
||||
founddialogue=_"Having trouble, eh? Never worry, lads, we'll sort 'em out soon enough!",
|
||||
image="units/dwarves/scout.png",
|
||||
name="Dwarvish Scout",
|
||||
},
|
||||
["Drake Fighter"] = {
|
||||
founddialogue=_"The ancient spirits tell me my destiny lies with yours. My sword is at your command.",
|
||||
image="units/drakes/fighter.png",
|
||||
name="Drake Fighter",
|
||||
},
|
||||
["Drake Clasher"] = {
|
||||
founddialogue=_"Stand fast, for I bring you the strength of dragons to assist you in your battle!",
|
||||
image="units/drakes/clasher.png",
|
||||
name="Drake Clasher",
|
||||
},
|
||||
["Drake Burner"] = {
|
||||
founddialogue=_"Today is a most auspicious day for you, for I deem you worthy of the power of dragonfire. Show me your foes and I will incinerate them!",
|
||||
image="units/drakes/burner.png",
|
||||
name="Drake Burner",
|
||||
alt_reply = { {
|
||||
race="drake",
|
||||
reply=_"Perfect. We can always use more fire power.",
|
||||
} }
|
||||
},
|
||||
["Saurian Augur"] = {
|
||||
founddialogue=_"You no fight good enough, no have saurian way. I show you way of saurian!",
|
||||
image="units/saurians/augur/augur.png",
|
||||
name="Saurian Augur",
|
||||
alt_reply = { {
|
||||
race="lizard",
|
||||
reply=_"Sure, bro...",
|
||||
} }
|
||||
},
|
||||
["Drake Glider"] = {
|
||||
founddialogue=_"You may be out to take over the land and the seas, but you'll never get anywhere without control of the skies. Fortunately I'm here to help you!",
|
||||
image="units/drakes/glider.png",
|
||||
name="Drake Glider",
|
||||
alt_reply = { {
|
||||
race="gryphon,bats",
|
||||
reply=_"Cool. We could always need more air power.",
|
||||
} }
|
||||
},
|
||||
["Saurian Skirmisher"] = {
|
||||
founddialogue=_"Tribe fall long time ago, now tribe lost. This last fight of tribe. I fight with you, make last very great!",
|
||||
image="units/saurians/skirmisher/skirmisher.png",
|
||||
name="Saurian Skirmisher",
|
||||
},
|
||||
["Skeleton"] = {
|
||||
founddialogue=_"Don't hit me! I'm just your average regular friendly talking skeleton, see? Looks like you fellows could use some help!",
|
||||
image="units/undead-skeletal/skeleton/skeleton.png",
|
||||
name="Skeleton",
|
||||
},
|
||||
["Skeleton Archer"] = {
|
||||
founddialogue=_"I am called forth from eternal rest, bound to follow he who called me. Show me the enemy, master!",
|
||||
image="units/undead-skeletal/archer.png",
|
||||
name="Skeleton Archer",
|
||||
},
|
||||
["Ghoul"] = {
|
||||
founddialogue=_"I say, old sport! It looks like you've got a spot of bother. Well, chin up, I say! I'm sure we'll make a simply smashing team-up. We can sort this lot out and be done by tea, what?",
|
||||
image="units/undead/ghoul.png",
|
||||
name="Ghoul",
|
||||
reply=_"Have at thee, unholy abomin... wait, huh?",
|
||||
alt_reply = { {
|
||||
race="undead,bats",
|
||||
reply=_"Excellent. We could always use more help.",
|
||||
} }
|
||||
},
|
||||
["Dark Adept"] = {
|
||||
founddialogue=_"You may not trust me or my reasons, but it seems you are not in a position to be choosy about your allies. Let me assist you and you just may survive.",
|
||||
image="units/undead-necromancers/adept.png",
|
||||
name="Dark Adept",
|
||||
},
|
||||
["Ghost"] = {
|
||||
founddialogue=_"Who calls me from my slumber? I sense a great battle being joined. Point me towards the enemy and I will feast upon their very souls!",
|
||||
image="units/undead/ghost-s-2.png",
|
||||
name="Ghost",
|
||||
},
|
||||
["Vampire Bat"] = {
|
||||
founddialogue=_"Skreeeeeeee!",
|
||||
image="units/undead/bat-se-3.png",
|
||||
name="Vampire Bat",
|
||||
reply=_"This creature seems unusually intelligent for its kind. Perhaps it will help us!",
|
||||
alt_reply = { {
|
||||
race="undead,bats",
|
||||
reply=_"Excellent. We could always use more help.",
|
||||
} }
|
||||
},
|
||||
["Young Ogre"] = {
|
||||
founddialogue=_"You friend are? I friend help!",
|
||||
image="units/ogres/young-ogre.png",
|
||||
name="Young Ogre",
|
||||
alt_reply = { {
|
||||
race="ogre,troll",
|
||||
reply=_"Me friend. We can play together.",
|
||||
} }
|
||||
},
|
||||
["Thug"] = {
|
||||
founddialogue=_"What, you want my help? A guy like me? Huh, that's rich. Oh well... let's give it a shot, eh?",
|
||||
image="units/human-outlaws/thug.png",
|
||||
name="Thug",
|
||||
},
|
||||
["Goblin Spearman"] = {
|
||||
founddialogue=_"Ah, please no hurtings me! I helps you, see?",
|
||||
image="units/goblins/spearman.png",
|
||||
name="Goblin Spearman",
|
||||
reply=_"Fine. We could need a small help.",
|
||||
alt_reply = { {
|
||||
race="orc,troll,dwarf,ogre,gryphon,wolf",
|
||||
reply=_"Excellent. We could always need cannon fodder.",
|
||||
}, {
|
||||
race="goblin",
|
||||
reply=_"Excellent. We could always use more help.",
|
||||
} }
|
||||
},
|
||||
["Walking Corpse"] = {
|
||||
founddialogue=_"...",
|
||||
image="units/undead/zombie.png",
|
||||
name="Walking Corpse",
|
||||
reply=_"Odd, it doesn't seem to attack. I wonder if we can use it?",
|
||||
alt_reply = { {
|
||||
race="undead,bats",
|
||||
reply=_"Excellent. We could always use more help.",
|
||||
type="Dark Adept,Dark Sorcerer,Necromancer,Lich",
|
||||
} }
|
||||
},
|
||||
["Ruffian"] = {
|
||||
founddialogue=_"Oooh oooh oooh! I want to help! Pick me, pick me!",
|
||||
name="Ruffian",
|
||||
reply=_"...fine. I guess.",
|
||||
alt_reply = { {
|
||||
race="human",
|
||||
reply=_"Excellent. We could always use more help.",
|
||||
} }
|
||||
},
|
||||
["Peasant"] = {
|
||||
founddialogue=_"Oooh oooh oooh! I want to help! Pick me, pick me!",
|
||||
name="Peasant",
|
||||
reply=_"...fine. I guess.",
|
||||
alt_reply = { {
|
||||
race="human",
|
||||
reply=_"Excellent. We could always use more help.",
|
||||
} }
|
||||
},
|
||||
["Woodsman"] = {
|
||||
founddialogue=_"Ho there, friends! I am but a soldier of humble circumstances, yet long have I dreamed of joining great wars beyond our shores. Let me join your mission!",
|
||||
name="Woodsman",
|
||||
},
|
||||
["Dune Herbalist"] = {
|
||||
founddialogue=_"Long have I studied the ways of lore, and I have much wisdom to offer. Allow me to guide you on your quest and together we will accomplish great things!",
|
||||
image="units/dunefolk/herbalist.png",
|
||||
name="Dune Herbalist",
|
||||
},
|
||||
["Dune Soldier"] = {
|
||||
founddialogue=_"I too have come a long way to this strange land. Perhaps we were destined to join blades here.",
|
||||
image="units/dunefolk/soldier.png",
|
||||
name="Dune Soldier",
|
||||
},
|
||||
["Dune Rover"] = {
|
||||
founddialogue=_"Ho there, friends! I am but a soldier of humble circumstances, yet long have I dreamed of joining great wars beyond our shores. Let me join your mission!",
|
||||
image="units/dunefolk/rover.png",
|
||||
name="Dune Rover",
|
||||
},
|
||||
["Dune Piercer"] = {
|
||||
founddialogue=_"Heh, looks like you whelps might be getting in over your heads. Good thing I'm here now to win this fight for ya, huh?",
|
||||
image="units/dunefolk/piercer.png",
|
||||
name="Dune Piercer",
|
||||
},
|
||||
["Dune Burner"] = {
|
||||
founddialogue=_"You may not trust me or my reasons, but it seems you are not in a position to be choosy about your allies. Let me assist you and you just may survive.",
|
||||
image="units/dunefolk/burner.png",
|
||||
name="Dune Burner",
|
||||
},
|
||||
["Dune Rider"] = {
|
||||
founddialogue=_"A soldier is no good without something to fight for. Let me fight for you!",
|
||||
image="units/dunefolk/rider.png",
|
||||
name="Dune Rider",
|
||||
},
|
||||
}
|
||||
return type_infos
|
||||
-- generated vai regex from original data:
|
||||
-- regex1:
|
||||
-- \[[A-Z][a-zA-Z_]+\](.*?)type="([A-Za-z_ ]+)"\r\n(.*?)\[/[A-Z][a-zA-Z_]+\]
|
||||
-- to
|
||||
-- ["\2"] = { \1 \3}
|
||||
--
|
||||
-- regex2:
|
||||
-- \[alt_reply\](.*?)\[/alt_reply\]
|
||||
-- to
|
||||
-- alt_reply = { { \1 } }
|
||||
-- + handfix to fix trypes with nultiple alt replies.
|
||||
|
||||
|
266
data/campaigns/World_Conquest/lua/game_mechanics/utils.lua
Normal file
|
@ -0,0 +1,266 @@
|
|||
local on_event = wesnoth.require("on_event")
|
||||
|
||||
local wc2_utils = {}
|
||||
|
||||
function wc2_utils.split_to_array(s, res)
|
||||
res = res or {}
|
||||
for part in tostring(s or ""):gmatch("[^%s,][^,]*") do
|
||||
table.insert(res, part)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function wc2_utils.split_to_set(s, res)
|
||||
res = res or {}
|
||||
for part in tostring(s or ""):gmatch("[^%s,][^,]*") do
|
||||
res[part] = true
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function wc2_utils.set_to_array(s, res)
|
||||
res = res or {}
|
||||
for k,v in pairs(s) do
|
||||
table.insert(res, k)
|
||||
end
|
||||
table.sort( res )
|
||||
return res
|
||||
end
|
||||
|
||||
|
||||
function wc2_utils.remove_dublicates(t)
|
||||
local found = {}
|
||||
for i = #t, 1, -1 do
|
||||
local v = t[i]
|
||||
if found[v] then
|
||||
table.remove(t, i)
|
||||
else
|
||||
found[v] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--comma seperated list
|
||||
function wc2_utils.pick_random(str, generator)
|
||||
local s2 = wml.variables[str]
|
||||
if s2 ~= nil or generator then
|
||||
local array = s2 and wc2_utils.split_to_array(s2) or {}
|
||||
if #array == 0 and generator then
|
||||
array = generator()
|
||||
end
|
||||
local index = wesnoth.random(#array)
|
||||
local res = array[index]
|
||||
table.remove(array, index)
|
||||
wml.variables[str] = table.concat(array, ",")
|
||||
return res
|
||||
end
|
||||
end
|
||||
|
||||
local function filtered_from_array(array, filter)
|
||||
local possible_indicies = {}
|
||||
for i, v in ipairs(array) do
|
||||
if filter(v) then
|
||||
table.insert(possible_indicies, i)
|
||||
end
|
||||
end
|
||||
if #possible_indicies == 0 then
|
||||
return nil
|
||||
end
|
||||
local index = possible_indicies[wesnoth.random(#possible_indicies)]
|
||||
return index
|
||||
end
|
||||
|
||||
function wc2_utils.pick_random_filtered(str, generator, filter)
|
||||
local s2 = wml.variables[str]
|
||||
if s2 == nil and generator == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local array = s2 and wc2_utils.split_to_array(s2) or {}
|
||||
if #array == 0 and generator then
|
||||
array = generator()
|
||||
end
|
||||
local index = filtered_from_array(array, filter)
|
||||
if index == nil then
|
||||
array = generator()
|
||||
index = filtered_from_array(array, filter)
|
||||
end
|
||||
local res = array[index]
|
||||
table.remove(array, index)
|
||||
wml.variables[str] = table.concat(array, ",")
|
||||
return res
|
||||
end
|
||||
|
||||
--wml array
|
||||
function wc2_utils.pick_random_t(str)
|
||||
local size = wml.variables[str .. ".length"]
|
||||
if size ~= 0 then
|
||||
local index = wesnoth.random(size) - 1
|
||||
local res = wml.variables[str .. "[" .. index .. "]"]
|
||||
wml.variables[str .. "[" .. index .. "]"] = nil
|
||||
return res
|
||||
end
|
||||
end
|
||||
|
||||
--like table concat but for tstrings.
|
||||
function wc2_utils.concat(t, sep)
|
||||
local res = t[1]
|
||||
if not res then
|
||||
return ""
|
||||
end
|
||||
for i = 2, #t do
|
||||
-- uses .. so we dont hae to call tostring. so this function can still return a tstring.
|
||||
res = res .. sep .. t[i]
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function wc2_utils.range(a1,a2)
|
||||
if a2 == nil then
|
||||
a2 = a1
|
||||
a1 = 1
|
||||
end
|
||||
local res = {}
|
||||
for i = a1, a2 do
|
||||
res[i] = i
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function wc2_utils.facing_each_other(u1,u2)
|
||||
u1.facing = wesnoth.map.get_relative_dir(u1.x, u1.y, u2.x, u2.y)
|
||||
u2.facing = wesnoth.map.get_relative_dir(u2.x, u2.y, u1.x, u1.y)
|
||||
wesnoth.wml_actions.redraw {}
|
||||
end
|
||||
|
||||
function wc2_utils.has_no_advances(u)
|
||||
return #u.advances_to == 0
|
||||
end
|
||||
|
||||
local global_vars = setmetatable({}, {
|
||||
__index = function(self, namespace)
|
||||
return setmetatable({}, {
|
||||
__index = function(self, name)
|
||||
wml.variables.lua_global_variable = nil
|
||||
wesnoth.unsynced(function()
|
||||
wesnoth.wml_actions.get_global_variable {
|
||||
namespace = namespace,
|
||||
to_local = "lua_global_variable",
|
||||
from_global = name,
|
||||
immediate = true,
|
||||
}
|
||||
end)
|
||||
local res = wml.variables.lua_global_variable
|
||||
wml.variables.lua_global_variable = nil
|
||||
if res == "" then
|
||||
return nil
|
||||
end
|
||||
return res
|
||||
end,
|
||||
__newindex = function(self, name, val)
|
||||
wml.variables.lua_global_variable = val
|
||||
wesnoth.unsynced(function()
|
||||
wesnoth.wml_actions.set_global_variable {
|
||||
namespace = namespace,
|
||||
from_local = "lua_global_variable",
|
||||
to_global = name,
|
||||
immediate = true,
|
||||
}
|
||||
end)
|
||||
wml.variables.lua_global_variable = nil
|
||||
end,
|
||||
})
|
||||
end
|
||||
})
|
||||
|
||||
wc2_utils.global_vars = global_vars.wc2
|
||||
|
||||
if rawget(_G, "wc2_menu_filters") == nil then
|
||||
wc2_menu_filters = {}
|
||||
end
|
||||
|
||||
function wc2_utils.menu_item(t)
|
||||
local id_nospace = string.gsub(t.id, " ", "_")
|
||||
local cfg = {}
|
||||
on_event("start", function()
|
||||
wesnoth.wml_actions.set_menu_item {
|
||||
id = t.id,
|
||||
description = t.description,
|
||||
image = t.image,
|
||||
synced = t.synced,
|
||||
wml.tag.filter_location {
|
||||
lua_function="wc2_menu_filters." .. id_nospace,
|
||||
},
|
||||
}
|
||||
end)
|
||||
if t.handler then
|
||||
on_event("menu_item_" .. t.id, t.handler)
|
||||
end
|
||||
wc2_menu_filters[id_nospace] = t.filter
|
||||
end
|
||||
|
||||
|
||||
function wc2_utils.get_fstring(t, key)
|
||||
local args = wml.get_child(t, key .. "_data")
|
||||
if args then
|
||||
args = wc2_utils.get_fstring_all(args)
|
||||
else
|
||||
args = {}
|
||||
end
|
||||
return wesnoth.format(t[key], args)
|
||||
end
|
||||
|
||||
function wc2_utils.get_fstring_all(t)
|
||||
local res = {}
|
||||
for k,v in pairs(t) do
|
||||
res[k] = wc2_utils.get_fstring(t, k)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
-- populates wc2_utils.world_conquest_data, reads [world_conquest_data] from all [resource]s and [era]
|
||||
function wc2_utils.load_wc2_data()
|
||||
if wc2_utils.world_conquest_data == nil then
|
||||
local data_dict = {}
|
||||
local ignore_list = {}
|
||||
for i,res_id in ipairs(wesnoth.game_config.active_resources) do
|
||||
local ressource = wesnoth.get_resource(res_id)
|
||||
local world_conquest_data = wml.get_child(ressource, "world_conquest_data")
|
||||
if world_conquest_data then
|
||||
for ignore in wml.child_range(world_conquest_data, "ignore") do
|
||||
ignore_list[ignore.id] = true
|
||||
end
|
||||
table.insert(data_dict, {id=res_id, data = world_conquest_data})
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(data_dict, {id="era", data = wesnoth.game_config.era})
|
||||
|
||||
|
||||
-- make sure the result does not depend on the order in which these addons are loaded.
|
||||
table.sort(data_dict, function(a,b) return a.id<b.id end)
|
||||
|
||||
|
||||
wc2_utils.world_conquest_data = {}
|
||||
for i, v in ipairs(data_dict) do
|
||||
if not ignore_list[v.id] then
|
||||
for i2, tag in ipairs(v.data) do
|
||||
local tagname = tag[1]
|
||||
wc2_utils.world_conquest_data[tagname] = wc2_utils.world_conquest_data[tagname] or {}
|
||||
table.insert( wc2_utils.world_conquest_data[tagname], tag )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- reads the tag @a tagnaem from [world_conquest_data] provided by any of the ressoucrs or eras used in the game.
|
||||
-- returns a wml table that contains only tagname subtags.
|
||||
function wc2_utils.get_wc2_data(tagname)
|
||||
wc2_utils.load_wc2_data()
|
||||
--todo: maybe we shoudl clear wc2_utils.world_conquest_data[tagname] afterwards ?
|
||||
return wc2_utils.world_conquest_data[tagname]
|
||||
end
|
||||
|
||||
|
||||
return wc2_utils
|
|
@ -0,0 +1,277 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local dialog = wc2_wiki_dialog
|
||||
|
||||
function wesnoth.set_dialog_text(text, ...)
|
||||
wesnoth.set_dialog_markup(true, ...)
|
||||
wesnoth.set_dialog_value(text, ...)
|
||||
end
|
||||
|
||||
function wesnoth.wml_actions.wc2_show_wocopedia(cfg)
|
||||
|
||||
local show_help_mechanics = cfg.show_mechanics ~= false
|
||||
local show_help_training = cfg.show_training ~= false
|
||||
local show_help_factions = cfg.show_factions ~= false
|
||||
local show_help_artifacts = cfg.show_artifacts ~= false
|
||||
local show_help_settings = cfg.show_settings ~= false
|
||||
local show_help_feedback = cfg.show_feedback ~= false
|
||||
-- maps the treeview rows to pagenumber in the help page.
|
||||
local index_map = {}
|
||||
local desc_index = 1
|
||||
local ti = {1}
|
||||
local function add_index()
|
||||
index_map[table.concat(ti, "_")] = desc_index
|
||||
desc_index = desc_index + 1
|
||||
ti[#ti] = ti[#ti] + 1
|
||||
end
|
||||
local function tree_enter_mode()
|
||||
ti[#ti] = ti[#ti] - 1
|
||||
table.insert(ti, 1)
|
||||
end
|
||||
local function leave_enter_mode()
|
||||
table.remove(ti)
|
||||
ti[#ti] = ti[#ti] + 1
|
||||
end
|
||||
local current_side = wesnoth.get_viewing_side()
|
||||
local preshow = function()
|
||||
local str_cat_mechnics = _ "Game Mechanics"
|
||||
local str_des_mechnics = cfg.mechanics_text or
|
||||
_ "<b>Gold</b>:\n" ..
|
||||
_ "Carryover is 15%, comunitary and avoid negative amounts. Early finish bonus is superior to village control, but it is not directly related to their amount.\n\n" ..
|
||||
_ "<b>Autorecall</b>:\n" ..
|
||||
_ "Units with trait HEROIC are recalled at start of each scenario with no cost (up to castle size).\n\n" ..
|
||||
_ "<b>Recall Cost</b>:\n" ..
|
||||
_ "Units costing less than 17 gold are cheaper to recall.\n\n" ..
|
||||
_ "<b>Trainings</b>:\n" ..
|
||||
_ "Every time you recruit a new unit, your trainings levels will be applied. Every chance will do different dice rolls, if a unit gains training beneficts, you can see them in a trait \"trained\".\n\n" ..
|
||||
_ "<b>Upkeep</b>:\n" ..
|
||||
_ "Units with trait HEROIC or holding any magic ITEM have FREE upkeep.\n\n" ..
|
||||
_ "<b>Bonus Points</b>:\n" ..
|
||||
_ "In every scenario the game generates as many bonus points on the map as there are players in the game, the bonus points can be picked up by player units and either contain artifacts, loyal units or training.\n\n" ..
|
||||
_ "<b>Army discipline</b>:\n" ..
|
||||
_ "At scenarios 1 to 3, for each training level player already own, trainers found have 2% to 4% chance to become advanced trainers (provide 2 levels). Becomes irrelevant from scenario 4 because all trainers always will be advanced.\n\n" ..
|
||||
""
|
||||
local str_cat_feedback = _ "Feedback"
|
||||
local str_des_feedback =
|
||||
_ "<b>Feedback</b>:\n" ..
|
||||
_ "For feedback plase either post in the Word conquest II thread in the official wesnoth forum https://r.wesnoth.org/t39651 or file an issue at github https://github.com/gfgtdf/World_Conquest_II/issues .\n\n" ..
|
||||
""
|
||||
local str_cat_abilities = _ "Abilities"
|
||||
local str_des_abilities =
|
||||
_ "Ability <b>Autorecall</b>:\n" ..
|
||||
_ "Units with trait HEROIC are recalled at start of each scenario with no cost (up to castle size).\n\n" ..
|
||||
""
|
||||
local str_cat_training = _ "Training"
|
||||
local str_des_training = _ "<b>Training</b>\nTraining improves newly recruited units, it has no effect on already recruited units. The follwing list shows all available trainings, the training you currently have is marked in green."
|
||||
local str_cat_items = _ "Artifacts"
|
||||
local str_des_items = _ "<b>Items</b>\nItems can be given to units to make them stronger. You can get artifcats in three ways: 1) By choosing an item as your starting bonus, 2) By finding it on a map in a bonus point, 3) By dropping from enemies in later scenarios. Note however that not all units can pickup all items."
|
||||
local str_cat_era = _ "Factions"
|
||||
local str_des_era = _ "<b>Factions</b>\n The Word Conquest 2 era consists of faction that are build of pairs of mainline faction of which at one has a healer available (Drakes, Rebels and Loyalists), and one does not (Orcs, Dwarves and Undead) the recruilist is also organized in pairs so that you sometimes have to recruit a different units before you can recruit the units that you want. The available heroes, desertes and random leaders also depend on your factions, the items you can get do not depend on the faction you choose."
|
||||
local str_cat_settings = _ "Settings"
|
||||
|
||||
---- add general topic ----
|
||||
if show_help_mechanics then
|
||||
wesnoth.add_dialog_tree_node("category", ti[1], "left_tree")
|
||||
wesnoth.set_dialog_value(str_cat_mechnics, "left_tree", ti[1], "training_name")
|
||||
wesnoth.set_dialog_value(true, "left_tree", ti[1])
|
||||
wesnoth.add_dialog_tree_node("simpletext", -1, "details")
|
||||
wesnoth.set_dialog_text(str_des_mechnics, "details", desc_index, "label")
|
||||
add_index()
|
||||
end
|
||||
if show_help_training then
|
||||
---- add general training topic ----
|
||||
wesnoth.add_dialog_tree_node("category", ti[1], "left_tree")
|
||||
wesnoth.set_dialog_value(str_cat_training, "left_tree", ti[1], "training_name")
|
||||
wesnoth.set_dialog_value(true, "left_tree", ti[1])
|
||||
wesnoth.add_dialog_tree_node("simpletext", -1, "details")
|
||||
wesnoth.set_dialog_text(str_des_training, "details", desc_index, "label")
|
||||
add_index()
|
||||
tree_enter_mode()
|
||||
-- add specific training pages
|
||||
for i = 1, #wc2_training.get_list() do
|
||||
local current_level = wc2_training.get_level(current_side, i)
|
||||
local function set_description(train_num, j)
|
||||
local desc = wc2_training.generate_message(i, train_num)
|
||||
if train_num == current_level then
|
||||
desc.caption = "<span color='#00FF00'>" .. desc.caption .. "</span>"
|
||||
desc.message = "<span color='#00FF00'>" .. desc.message .. "</span>"
|
||||
end
|
||||
wesnoth.add_dialog_tree_node("training_details", j, "details", desc_index, "tree_details")
|
||||
wesnoth.set_dialog_text(desc.caption, "details", desc_index, "tree_details", j, "training_caption")
|
||||
wesnoth.set_dialog_text(desc.message, "details", desc_index, "tree_details", j, "training_description")
|
||||
end
|
||||
local trainer = wc2_training.get_trainer(i)
|
||||
wesnoth.add_dialog_tree_node("training_category", i, "left_tree", ti[1])
|
||||
wesnoth.set_dialog_value(trainer.name, "left_tree", ti[1], ti[2], "training_name")
|
||||
set_description(1, 1)
|
||||
for j = 2, #trainer.grade - 1, 1 do
|
||||
wesnoth.add_dialog_tree_node("seperator", 2*j - 2, "details", desc_index, "tree_details")
|
||||
set_description(j, 2*j - 1)
|
||||
end
|
||||
add_index()
|
||||
end
|
||||
leave_enter_mode()
|
||||
end
|
||||
if show_help_factions then
|
||||
local function type_icon(ut)
|
||||
local icon = ut.icon
|
||||
if icon and icon ~= "" then
|
||||
return icon
|
||||
else
|
||||
return ut.image
|
||||
end
|
||||
end
|
||||
---- add general factions topic ----
|
||||
local era_wml = wesnoth.game_config.era
|
||||
wesnoth.add_dialog_tree_node("category", ti[1], "left_tree")
|
||||
wesnoth.set_dialog_value(str_cat_era, "left_tree", ti[1], "training_name")
|
||||
wesnoth.set_dialog_value(true, "left_tree", ti[1])
|
||||
wesnoth.add_dialog_tree_node("simpletext", -1, "details")
|
||||
wesnoth.set_dialog_text(str_des_era, "details", desc_index, "label")
|
||||
add_index()
|
||||
tree_enter_mode()
|
||||
for i, faction_info in ipairs(wc2_era.factions_wml) do
|
||||
local faction_wml = wml.get_child(era_wml, "multiplayer_side", faction_info.id)
|
||||
wesnoth.add_dialog_tree_node("training_category", ti[2], "left_tree", ti[1])
|
||||
wesnoth.set_dialog_value(faction_info.name, "left_tree", ti[1], ti[2], "training_name")
|
||||
wesnoth.add_dialog_tree_node("faction_info", -1, "details")
|
||||
j = 0
|
||||
for p_wml in wml.child_range(faction_info, "pair") do
|
||||
j = j + 1
|
||||
local p = wc2_utils.split_to_array(p_wml.types)
|
||||
local ut1 = wesnoth.unit_types[p[1]] or error("invald unit type" .. tostring(p[1]))
|
||||
local ut2 = wesnoth.unit_types[p[2]] or error("invald unit type" .. tostring(p[2]))
|
||||
|
||||
wesnoth.add_dialog_tree_node("recruit_pair", j, "details", desc_index, "recruit_pairs")
|
||||
wesnoth.set_dialog_text(ut1.name, "details", desc_index, "recruit_pairs", j, "label1")
|
||||
print(tostring(ut1.icon or ut1.image))
|
||||
wesnoth.set_dialog_value(type_icon(ut1), "details", desc_index, "recruit_pairs", j, "image1")
|
||||
wesnoth.set_dialog_text(ut2.name, "details", desc_index, "recruit_pairs", j, "label2")
|
||||
wesnoth.set_dialog_value(type_icon(ut2), "details", desc_index, "recruit_pairs", j, "image2")
|
||||
end
|
||||
local deserters_names = wesnoth.format_conjunct_list("", wc2_era.expand_hero_names(faction_info.deserters))
|
||||
wesnoth.set_dialog_text(deserters_names, "details", desc_index, "deserters")
|
||||
local deserters_names = wesnoth.format_conjunct_list("", wc2_era.expand_hero_names(faction_info.commanders))
|
||||
wesnoth.set_dialog_text(deserters_names, "details", desc_index, "commanders")
|
||||
local deserters_names = wesnoth.format_conjunct_list("", wc2_era.expand_hero_names(faction_info.heroes, true))
|
||||
wesnoth.set_dialog_text(deserters_names, "details", desc_index, "heroes")
|
||||
|
||||
if faction_wml then
|
||||
local random_leaders = {}
|
||||
for i,v in ipairs(wc2_utils.split_to_array(faction_wml.random_leader)) do
|
||||
table.insert(random_leaders, wesnoth.unit_types[v].name)
|
||||
end
|
||||
random_leaders = wesnoth.format_conjunct_list("", random_leaders)
|
||||
wesnoth.set_dialog_text(random_leaders, "details", desc_index, "random_leaders")
|
||||
else
|
||||
wesnoth.set_dialog_visible(false, "details", desc_index, "tit_random_leaders")
|
||||
end
|
||||
|
||||
add_index()
|
||||
end
|
||||
leave_enter_mode()
|
||||
end
|
||||
---- add general bonus point topic ----
|
||||
--wesnoth.add_dialog_tree_node("category", ti[1], "left_tree")
|
||||
--wesnoth.set_dialog_value(str_cat_bonus, "left_tree", ti[1], "training_name")
|
||||
--wesnoth.add_dialog_tree_node("simpletext", -1, "details")
|
||||
--wesnoth.set_dialog_text(str_des_bonus, "details", desc_index, "label")
|
||||
--add_index()
|
||||
|
||||
if show_help_artifacts then
|
||||
local str_not_for_enemies = _ " (not available for enemies)"
|
||||
local str_not_for_players = _ " (not available for players)"
|
||||
|
||||
wesnoth.add_dialog_tree_node("category", ti[1], "left_tree")
|
||||
wesnoth.set_dialog_value(str_cat_items, "left_tree", ti[1], "training_name")
|
||||
wesnoth.add_dialog_tree_node("artifact_list", -1, "details")
|
||||
wesnoth.set_dialog_text(str_des_items, "details", desc_index, "desc")
|
||||
|
||||
for i, artifact in ipairs(wc2_artifacts.get_artifact_list()) do
|
||||
local artifact_icon = artifact.icon or ""
|
||||
local artifact_name = artifact.name or ""
|
||||
local artifact_desc = artifact.description or ""
|
||||
local not_available = wc2_utils.split_to_set(artifact.not_available or "")
|
||||
|
||||
if not_available.player then
|
||||
artifact_name = artifact_name .. str_not_for_players
|
||||
end
|
||||
if not_available.enemy then
|
||||
artifact_name = artifact_name .. str_not_for_enemies
|
||||
end
|
||||
wesnoth.add_dialog_tree_node("artifact", i, "details", desc_index, "artifact_list_tv")
|
||||
wesnoth.set_dialog_value(artifact_icon, "details", desc_index, "artifact_list_tv", i, "image")
|
||||
wesnoth.set_dialog_value(artifact_name .. "\n" .. artifact_desc, "details", desc_index, "artifact_list_tv", i, "label")
|
||||
end
|
||||
add_index()
|
||||
end
|
||||
|
||||
if show_help_settings then
|
||||
wesnoth.add_dialog_tree_node("category", ti[1], "left_tree")
|
||||
wesnoth.set_dialog_value(str_cat_settings, "left_tree", ti[1], "training_name")
|
||||
wesnoth.set_dialog_value(true, "left_tree", ti[1])
|
||||
wesnoth.add_dialog_tree_node("settings", -1, "details")
|
||||
wesnoth.set_dialog_value(not not wml.variables["wc2_config_enable_pya"], "details", desc_index, "checkbox_use_pya")
|
||||
wesnoth.set_dialog_active(false, "details", desc_index, "checkbox_use_pya")
|
||||
wesnoth.set_dialog_value(not not wml.variables["wc2_config_enable_unitmarker"], "details", desc_index, "checkbox_use_markers")
|
||||
wesnoth.set_dialog_active(false, "details", desc_index, "checkbox_use_markers")
|
||||
wesnoth.set_dialog_value(not not wml.variables["wc2_config_experimental_pickup"], "details", desc_index, "checkbox_use_pickup")
|
||||
wesnoth.set_dialog_active(false, "details", desc_index, "checkbox_use_pickup")
|
||||
wesnoth.set_dialog_text(wml.variables["wc2_host_version"] or "unknown", "details", desc_index, "label_version")
|
||||
wesnoth.set_dialog_text(wml.variables["wc2_difficulty.name"] or "unknown", "details", desc_index, "label_difficulty")
|
||||
|
||||
wesnoth.set_dialog_value(not wc2_utils.global_vars.skip_pickup_dialog, "details", desc_index, "checkbox_show_pickup_confirmation")
|
||||
wesnoth.set_dialog_active(true, "details", desc_index, "checkbox_show_pickup_confirmation")
|
||||
local desc_index_copy = desc_index
|
||||
wesnoth.set_dialog_callback(function()
|
||||
wc2_utils.global_vars.skip_pickup_dialog = not wesnoth.get_dialog_value("details", desc_index_copy, "checkbox_show_pickup_confirmation")
|
||||
end, "details", desc_index_copy, "checkbox_show_pickup_confirmation")
|
||||
|
||||
local mp_settings = wesnoth.game_config.mp_settings
|
||||
if mp_settings and mp_settings.active_mods then
|
||||
--FIXME: mp_settings.active_mods was removed during an internal refactor of the c++ mp_settings object.
|
||||
-- but maybe we shouldn't need this in the mainline version anyways.
|
||||
wesnoth.set_dialog_text(mp_settings.active_mods, "details", desc_index, "label_activemods")
|
||||
end
|
||||
add_index()
|
||||
end
|
||||
if show_help_feedback then
|
||||
wesnoth.add_dialog_tree_node("category", ti[1], "left_tree")
|
||||
wesnoth.set_dialog_value(str_cat_feedback, "left_tree", ti[1], "training_name")
|
||||
wesnoth.set_dialog_value(true, "left_tree", ti[1])
|
||||
wesnoth.add_dialog_tree_node("simpletext", -1, "details")
|
||||
wesnoth.set_dialog_text(str_des_feedback, "details", desc_index, "label")
|
||||
add_index()
|
||||
end
|
||||
wesnoth.set_dialog_focus("left_tree")
|
||||
|
||||
wesnoth.set_dialog_callback(function()
|
||||
local selected = wesnoth.get_dialog_value("left_tree")
|
||||
local selected_page_index = index_map[table.concat(selected, '_')]
|
||||
if selected_page_index ~= nil then
|
||||
wesnoth.set_dialog_value(selected_page_index, "details")
|
||||
end
|
||||
end, "left_tree")
|
||||
end
|
||||
|
||||
wesnoth.show_dialog(dialog, preshow)
|
||||
end
|
||||
|
||||
wc2_utils.menu_item {
|
||||
id = "5_WCT_Wocopedia_Option",
|
||||
description = _ "WoCopedia",
|
||||
image= "help/closed_section.png~SCALE(18,17)",
|
||||
synced = false,
|
||||
filter = function(x, y)
|
||||
local u = wesnoth.get_unit(x, y)
|
||||
if wc2_artifacts.is_item_at(x, y) then
|
||||
return false
|
||||
end
|
||||
return not (u and u.side == wesnoth.current.side)
|
||||
end,
|
||||
handler = function(cx)
|
||||
wesnoth.wml_actions.wc2_show_wocopedia {
|
||||
x = cx.x1,
|
||||
y = cx.y1,
|
||||
}
|
||||
end
|
||||
}
|
|
@ -0,0 +1,711 @@
|
|||
local _ = wesnoth.textdomain 'wesnoth-World_Conquest'
|
||||
local T = wml.tag
|
||||
|
||||
local function GUI_FORCE_WIDGET_MINIMUM_SIZE(w,h, content)
|
||||
return T.stacked_widget {
|
||||
definition = "default",
|
||||
T.stack {
|
||||
T.layer {
|
||||
T.row {
|
||||
T.column {
|
||||
T.spacer {
|
||||
definition = "default",
|
||||
width = w,
|
||||
height = h
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
T.layer {
|
||||
T.row {
|
||||
grow_factor = 1,
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_grow = "true",
|
||||
vertical_grow = "true",
|
||||
content
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
local GUI_HORIZONTAL_SPACER_LINE = T.row {
|
||||
grow_factor = 0,
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
border = "all",
|
||||
border_size = 10,
|
||||
horizontal_grow = true,
|
||||
T.drawing {
|
||||
definition = "default",
|
||||
width = "(width)",
|
||||
height = 1,
|
||||
T.draw {
|
||||
T.line {
|
||||
x1 = 0,
|
||||
y1 = 0,
|
||||
x2 = "(width - 1)",
|
||||
y2 = 0,
|
||||
color = "114, 79, 46, 255",
|
||||
thickness = 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
maximum_width = 900,
|
||||
T.helptip { id = "tooltip_large" }, -- mandatory field
|
||||
T.tooltip { id = "tooltip_large" }, -- mandatory field
|
||||
|
||||
T.linked_group { id = "artifact_icon", fixed_width = true },
|
||||
T.linked_group { id = "artifact_name", fixed_width = true },
|
||||
T.linked_group { id = "recruit_icon", fixed_width = true },
|
||||
T.linked_group { id = "recruit_name", fixed_width = true },
|
||||
|
||||
T.grid {
|
||||
T.row {
|
||||
grow_factor = 1,
|
||||
T.column {
|
||||
border = "all",
|
||||
border_size = 5,
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
definition = "title",
|
||||
label = _"WoCopedia",
|
||||
id = "title"
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
grow_factor = 1,
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
border = "all",
|
||||
border_size = 5,
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.tree_view {
|
||||
id = "left_tree",
|
||||
definition = "default",
|
||||
horizontal_scrollbar_mode = "never",
|
||||
vertical_scrollbar_mode = "never",
|
||||
indentation_step_size = 35,
|
||||
T.node {
|
||||
id = "training_category",
|
||||
T.node_definition {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_grow = true,
|
||||
T.toggle_panel {
|
||||
id = "tree_view_node_label",
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
id = "training_name",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
T.node {
|
||||
id = "category",
|
||||
T.node_definition {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 0,
|
||||
horizontal_grow = true,
|
||||
T.toggle_button {
|
||||
id = "tree_view_node_toggle",
|
||||
definition = "tree_view_node",
|
||||
},
|
||||
},
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_grow = true,
|
||||
T.toggle_panel {
|
||||
id = "tree_view_node_label",
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
id = "training_name",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
T.column {
|
||||
T.multi_page {
|
||||
id = "details",
|
||||
definition = "default",
|
||||
horizontal_scrollbar_mode = "never",
|
||||
T.page_definition {
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.scrollbar_panel {
|
||||
T.definition {
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.tree_view {
|
||||
id = "tree_details",
|
||||
definition = "default",
|
||||
horizontal_scrollbar_mode = "never",
|
||||
vertical_scrollbar_mode = "never",
|
||||
indention_step_size = 20,
|
||||
T.node {
|
||||
id = "training_details",
|
||||
T.node_definition {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
definition = "default_large",
|
||||
id = "training_caption",
|
||||
label = "default description",
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
id = "training_description",
|
||||
label = "default description",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
T.node {
|
||||
id = "scroll_details",
|
||||
T.node_definition {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
definition = "default_large",
|
||||
id = "training_caption",
|
||||
label = "default description",
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_alignment = "left",
|
||||
T.scroll_label {
|
||||
id = "training_description",
|
||||
label = "default description",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
T.node {
|
||||
id = "seperator",
|
||||
T.node_definition {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
horizontal_grow = true,
|
||||
T.spacer {
|
||||
height = 20,
|
||||
width = 20,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
T.page_definition {
|
||||
id="simpletext",
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
vertical_grow = true,
|
||||
T.scroll_label {
|
||||
id = "label",
|
||||
label = "Text",
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
T.page_definition {
|
||||
id="artifact_list",
|
||||
vertical_grow = true,
|
||||
T.row {
|
||||
T.column {
|
||||
vertical_grow = true,
|
||||
T.grid {
|
||||
--T.row {
|
||||
-- T.column {
|
||||
-- grow_factor = 1,
|
||||
-- vertical_grow = true,
|
||||
-- T.label {
|
||||
-- id = "title",
|
||||
-- label = "Artifacts",
|
||||
-- }
|
||||
-- }
|
||||
--},
|
||||
T.row {
|
||||
T.column {
|
||||
T.scroll_label {
|
||||
vertical_scrollbar_mode = "never",
|
||||
id = "desc",
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
T.tree_view {
|
||||
vertical_grow = true,
|
||||
id = "artifact_list_tv",
|
||||
definition = "default",
|
||||
horizontal_scrollbar_mode = "never",
|
||||
vertical_scrollbar_mode = "always",
|
||||
indentation_step_size = 35,
|
||||
T.node {
|
||||
id = "artifact",
|
||||
horizontal_grow = true,
|
||||
T.node_definition {
|
||||
vertical_grow = true,
|
||||
T.row {
|
||||
horizontal_grow = true,
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
T.image {
|
||||
id="image",
|
||||
linked_group = "artifact_icon",
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
T.label {
|
||||
id="label",
|
||||
linked_group = "artifact_name",
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
grow_factor = 1,
|
||||
T.column {
|
||||
grow_factor = 0,
|
||||
vertical_grow = true,
|
||||
T.spacer {
|
||||
id = "aa",
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
T.page_definition {
|
||||
id="faction_info",
|
||||
vertical_grow = true,
|
||||
T.row {
|
||||
T.column {
|
||||
vertical_grow = true,
|
||||
horizontal_grow = true,
|
||||
T.grid {
|
||||
--T.row {
|
||||
-- T.column {
|
||||
-- grow_factor = 1,
|
||||
-- vertical_grow = true,
|
||||
-- T.label {
|
||||
-- id = "title",
|
||||
-- label = "Artifacts",
|
||||
-- }
|
||||
-- }
|
||||
--},
|
||||
T.row {
|
||||
T.column {
|
||||
T.scroll_label {
|
||||
vertical_scrollbar_mode = "never",
|
||||
id = "desc",
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
T.label {
|
||||
vertical_scrollbar_mode = "never",
|
||||
label = "<b>Recruits:</b>",
|
||||
use_markup = true,
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
T.tree_view {
|
||||
id = "recruit_pairs",
|
||||
definition = "default",
|
||||
horizontal_scrollbar_mode = "never",
|
||||
vertical_scrollbar_mode = "always",
|
||||
indentation_step_size = 35,
|
||||
T.node {
|
||||
id = "recruit_pair",
|
||||
horizontal_grow = true,
|
||||
T.node_definition {
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
T.image {
|
||||
id="image1",
|
||||
linked_group = "recruit_icon",
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
T.label {
|
||||
id="label1",
|
||||
linked_group = "recruit_name",
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
T.label {
|
||||
label="↔",
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
T.image {
|
||||
id="image2",
|
||||
linked_group = "recruit_icon",
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
T.label {
|
||||
id="label2",
|
||||
linked_group = "recruit_name",
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
T.label {
|
||||
vertical_scrollbar_mode = "never",
|
||||
label = "<b>Deserters:</b>",
|
||||
use_markup = true,
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow=true,
|
||||
T.scroll_label {
|
||||
vertical_scrollbar_mode = "never",
|
||||
id = "deserters",
|
||||
use_markup = true,
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
T.label {
|
||||
vertical_scrollbar_mode = "never",
|
||||
label = "<b>Commanders:</b>",
|
||||
use_markup = true,
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow=true,
|
||||
T.scroll_label {
|
||||
vertical_scrollbar_mode = "never",
|
||||
id = "commanders",
|
||||
use_markup = true,
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
T.label {
|
||||
vertical_scrollbar_mode = "never",
|
||||
label = "<b>Heroes:</b>",
|
||||
use_markup = true,
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow=true,
|
||||
T.scroll_label {
|
||||
vertical_scrollbar_mode = "never",
|
||||
id = "heroes",
|
||||
use_markup = true,
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
T.label {
|
||||
vertical_scrollbar_mode = "never",
|
||||
label = "<b>Random Leaders:</b>",
|
||||
id = "tit_random_leaders",
|
||||
use_markup = true,
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow=true,
|
||||
T.scroll_label {
|
||||
vertical_scrollbar_mode = "never",
|
||||
id = "random_leaders",
|
||||
use_markup = true,
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
grow_factor = 1,
|
||||
T.column {
|
||||
grow_factor = 0,
|
||||
vertical_grow = true,
|
||||
T.spacer {
|
||||
id = "aa",
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
T.page_definition {
|
||||
id="settings",
|
||||
vertical_grow = true,
|
||||
horizontal_grow = true,
|
||||
T.row {
|
||||
T.column {
|
||||
vertical_grow = true,
|
||||
horizontal_grow = true,
|
||||
T.grid {
|
||||
T.row {
|
||||
grow_factor = 0,
|
||||
T.column {
|
||||
grow_factor = 0,
|
||||
vertical_grow = false,
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
id = "title",
|
||||
label = "<b>Settings</b>\n ",
|
||||
use_markup=true,
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
grow_factor = 0,
|
||||
T.column {
|
||||
horizontal_grow=true,
|
||||
vertical_alignment="top",
|
||||
grow_factor = 1,
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_alignment="left",
|
||||
T.label {
|
||||
label = "Use WC2 PYA mod",
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
horizontal_alignment="right",
|
||||
T.toggle_button {
|
||||
label = "",
|
||||
id="checkbox_use_pya",
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_alignment="left",
|
||||
T.label {
|
||||
label = "Use WC2 Unitmarkers",
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
horizontal_alignment="right",
|
||||
T.toggle_button {
|
||||
label = "",
|
||||
id="checkbox_use_markers",
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_alignment="left",
|
||||
T.label {
|
||||
label = "Use WC2 experimental pickup",
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
horizontal_alignment="right",
|
||||
T.toggle_button {
|
||||
label = "",
|
||||
id="checkbox_use_pickup",
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_alignment="left",
|
||||
T.label {
|
||||
label = "Show pickup confirmation",
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
horizontal_alignment="right",
|
||||
T.toggle_button {
|
||||
label = "",
|
||||
id="checkbox_show_pickup_confirmation",
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_alignment="left",
|
||||
T.label {
|
||||
label = "difficulty",
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
horizontal_alignment="right",
|
||||
T.label {
|
||||
label = "",
|
||||
id="label_difficulty",
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_alignment="left",
|
||||
T.label {
|
||||
label = "WC2 version",
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
horizontal_alignment="right",
|
||||
T.label {
|
||||
label = "",
|
||||
id="label_version",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI_HORIZONTAL_SPACER_LINE,
|
||||
T.row {
|
||||
grow_factor = 0,
|
||||
T.column {
|
||||
grow_factor = 0,
|
||||
vertical_grow = false,
|
||||
horizontal_alignment = "left",
|
||||
T.label {
|
||||
id = "title_2",
|
||||
label = "<b>Active mods</b>\n ",
|
||||
use_markup=true,
|
||||
},
|
||||
},
|
||||
},
|
||||
T.row {
|
||||
grow_factor = 1,
|
||||
T.column {
|
||||
grow_factor = 0,
|
||||
horizontal_grow=true,
|
||||
vertical_alignment="top",
|
||||
T.scroll_label {
|
||||
id = "label_activemods",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
T.row {
|
||||
T.column {
|
||||
horizontal_grow = true,
|
||||
T.grid {
|
||||
T.row {
|
||||
T.column {
|
||||
grow_factor = 1,
|
||||
T.spacer {
|
||||
}
|
||||
},
|
||||
T.column {
|
||||
horizontal_alignment = "right",
|
||||
T.button {
|
||||
label = "Ok",
|
||||
id = "ok",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
4
data/campaigns/World_Conquest/lua/main.lua
Normal file
|
@ -0,0 +1,4 @@
|
|||
-- the main file for other addons that want to use the WC2 mechanics.
|
||||
|
||||
wc2_convert = wesnoth.require("./wml_converter.lua")
|
||||
wesnoth.dofile("./game_mechanics/_load.lua")
|
88
data/campaigns/World_Conquest/lua/map/distmap.lua
Normal file
|
@ -0,0 +1,88 @@
|
|||
|
||||
----------------------------------------------------------
|
||||
---- A utility class, to calculate distances of each ----
|
||||
---- tile to one given tile ----
|
||||
----------------------------------------------------------
|
||||
|
||||
|
||||
local Distmap = {}
|
||||
|
||||
function Distmap:create(w, h)
|
||||
local o = {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
o.w = w
|
||||
o.h = h
|
||||
o.data = {}
|
||||
for i = 1,w *h do
|
||||
o.data[#o.data + 1] = false
|
||||
end
|
||||
return o
|
||||
end
|
||||
|
||||
function Distmap:loc_to_index(loc)
|
||||
return loc[1] + 1 + loc[2] * self.w
|
||||
end
|
||||
|
||||
function Distmap:is_on_map(loc)
|
||||
local x, y= loc[1], loc[2]
|
||||
return x >= 0 and y >= 0 and y < self.h and x < self.w
|
||||
end
|
||||
|
||||
function Distmap:get(loc)
|
||||
return self.data[self:loc_to_index(loc)]
|
||||
end
|
||||
|
||||
|
||||
local adjacent_offset = {
|
||||
--odd x
|
||||
{ {0,-1}, {1,-1}, {1,0}, {0,1}, {-1,0}, {-1,-1} },
|
||||
--even x
|
||||
{ {0,-1}, {1,0}, {1,1}, {0,1}, {-1,1}, {-1,0} }
|
||||
}
|
||||
|
||||
function Distmap:adjacent_tiles(loc, filter)
|
||||
local x, y = loc[1], loc[2]
|
||||
local offsets = adjacent_offset[2 - (x % 2)]
|
||||
local res = {}
|
||||
for i, offset in ipairs(offsets) do
|
||||
local x2, y2 = x + offset[1], y + offset[2]
|
||||
if self:is_on_map({x2, y2}) and ((filter == nil) or filter(x2, y2)) then
|
||||
res[#res + 1] = { x2, y2}
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function Distmap:calculate_distances(locs, upto, filter)
|
||||
wesnoth.log("info", "calculate_distances " .. upto .. " " .. #locs)
|
||||
local todo = locs
|
||||
local data = self.data
|
||||
for i,loc in ipairs(todo) do
|
||||
data[self:loc_to_index(loc)] = 0
|
||||
end
|
||||
while #todo ~= 0 do
|
||||
local loc = todo[1]
|
||||
local loc_i = self:loc_to_index(loc)
|
||||
local dist = self.data[loc_i] + 1
|
||||
for i2, loc2 in ipairs(self:adjacent_tiles(loc, filter)) do
|
||||
local loc2_i = self:loc_to_index(loc2)
|
||||
if (data[loc2_i] or 999) > dist then
|
||||
data[loc2_i] = dist
|
||||
todo[#todo + 1] = loc2
|
||||
end
|
||||
end
|
||||
table.remove(todo, 1)
|
||||
end
|
||||
end
|
||||
|
||||
function Distmap:std_print(loc)
|
||||
local data = functional.map(self.data, function(v)
|
||||
return tostring(v or "nil")
|
||||
end)
|
||||
for i =1, self.h do
|
||||
std_print(table.concat(data, "\t,\t", 1 + (i-1)* self.w, i * self.w ))
|
||||
end
|
||||
end
|
||||
|
||||
return Distmap
|
70
data/campaigns/World_Conquest/lua/map/generator/classic.lua
Normal file
|
@ -0,0 +1,70 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
|
||||
local res = wct_generator_settings_arguments( length, villages, castle, iterations, size, players, island)
|
||||
res.max_lakes=10
|
||||
res.min_lake_height=150
|
||||
res.lake_size=125
|
||||
res.river_frequency=100
|
||||
res.temperature_size=size
|
||||
res.roads=20
|
||||
res.road_windiness=3
|
||||
|
||||
res.height = {
|
||||
-- list of common terrain types which come in at different heights, from highest to lowest
|
||||
dr_height(900, "Uh"),
|
||||
dr_height(800, "Uu"),
|
||||
dr_height(750, "Xu"),
|
||||
dr_height(725, "Mm^Xm"),
|
||||
dr_height(675, "Mm"),
|
||||
dr_height(550, "Hh"),
|
||||
dr_height(100, "Gg"),
|
||||
dr_height(30, "Ds"),
|
||||
dr_height(1, "Ww"),
|
||||
dr_height(0, "Wo"),
|
||||
}
|
||||
res.convert = {
|
||||
-- DR_CONVERT MIN_HT MAX_HT MIN_TMP MAX_TMP FROM TO
|
||||
-- water at cold becomes ice
|
||||
dr_convert(50, 999, 0, 50, "Ww, Wo", "Ai"),
|
||||
-- at low temperatures, snow appears
|
||||
dr_convert(50, 999, 0, 75, "Gg, Ds", "Aa"),
|
||||
-- hills at cold get snow on them
|
||||
dr_convert(0, 999, 0, 100, "Hh", "Ha"),
|
||||
-- savannah appears on mod temp and high
|
||||
dr_convert(250, 400, 500, 800, "Gg", "Gs"),
|
||||
-- swamp appears on low land, at mod temp
|
||||
dr_convert(0, 200, 400, 700, "Gg", "Ss"),
|
||||
-- forest appears at moderate temperatures
|
||||
dr_convert(0, 999, 320, 420, "Gg", "Gs^Fp"),
|
||||
dr_convert(0, 999, 320, 420, "Hh", "Hh^Fp"),
|
||||
-- jungle appears at mod high temperatures
|
||||
dr_convert(0, 999, 450, 520, "Gg,Gs", "Gs^Ft"),
|
||||
dr_convert(0, 999, 450, 520, "Hh", "Hh^Ft"),
|
||||
-- fungus appears at med temp and high
|
||||
dr_convert(825, 950, 500, 525, "Uu, Uh", "Uu^Uf"),
|
||||
dr_convert(825, 950, 550, 575, "Uu, Uh", "Uu^Uf"),
|
||||
dr_convert(825, 950, 600, 625, "Uu, Uh", "Uu^Uf"),
|
||||
-- lava appears at extreme temp and height
|
||||
dr_convert(800, 999, 850, 999, "Uu, Uh, Uu^Uf", "Ql"),
|
||||
-- desert appears at extreme temperatures
|
||||
dr_convert(0, 999, 800, 999, "Gg", "Dd"),
|
||||
-- dunes at extreme temp and mod elevation
|
||||
dr_convert(475, 550, 800, 999, "Ds, Hh", "Hd"),
|
||||
}
|
||||
res.road_cost = {
|
||||
wct_generator_road_cost_classic(),
|
||||
dr_road("Gs^Ft", "Re", 30),
|
||||
dr_road("Ds", "Re", 25),
|
||||
dr_bridge("Ww", "Ww^Bw", "Ce", 50),
|
||||
}
|
||||
res.village = {
|
||||
wct_generator_village(8, 5, 2, 4, 3, 4, 4, 3, 3, 3, 2, 1)
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gs, Gg, Gs^Fp, Hh",
|
||||
min_distance=12,
|
||||
}
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|
142
data/campaigns/World_Conquest/lua/map/generator/clayey.lua
Normal file
|
@ -0,0 +1,142 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
|
||||
local res = wct_generator_settings_arguments( length, villages, castle, iterations, size, players, island)
|
||||
res.max_lakes=35
|
||||
res.min_lake_height=250
|
||||
res.lake_size=100
|
||||
res.river_frequency=100
|
||||
res.temperature_size=size
|
||||
res.roads=0
|
||||
res.road_windiness=1
|
||||
res.height = {
|
||||
-- list of common terrain types which come in at different heights, from highest to lowest
|
||||
dr_height(955, "Uh"),
|
||||
dr_height(945, "Uu^Uf"),
|
||||
dr_height(900, "Uu"),
|
||||
dr_height(855, "Uh"),
|
||||
dr_height(845, "Uu^Uf"),
|
||||
dr_height(825, "Uu"),
|
||||
dr_height(775, "Xu"),
|
||||
dr_height(750, "Mm^Xm"),
|
||||
dr_height(700, "Mm"),
|
||||
dr_height(690, "Hh^Uf"),
|
||||
dr_height(660, "Hh^Fp"),
|
||||
dr_height(625, "Hh"),
|
||||
-- most rough terrain is added post generation
|
||||
dr_height(115, "Gg"),
|
||||
dr_height(30, "Ds"),
|
||||
dr_height(1, "Wwg"),
|
||||
dr_height(0, "Wog"),
|
||||
}
|
||||
res.convert = {
|
||||
wct_fix_river_into_ocean("g", 29),
|
||||
-- DR_CONVERT MIN_HT MAX_HT MIN_TMP MAX_TMP FROM TO
|
||||
-- lava appears at extreme temp and height
|
||||
dr_convert(800, 999, 850, 999, "Uu, Uh, Uu^Uf", "Ql"),
|
||||
-- DR_TEMPERATURE FROM MIN MAX TO),
|
||||
-- less wet flat as higher temperature
|
||||
dr_temperature("Gg", 720, 999, "Dd"),
|
||||
dr_temperature("Gg", 655, 720, "Rd"),
|
||||
dr_temperature("Gg", 570, 655, "Re"),
|
||||
dr_temperature("Gg", 435, 570, "Rb"),
|
||||
dr_temperature("Gg", 340, 435, "Gs"),
|
||||
}
|
||||
res.village = {
|
||||
-- flat villages
|
||||
dr_village {
|
||||
terrain = "Gg",
|
||||
convert_to="Gg^Vht",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Re, Rd, Rb, Gg, Gs, Re, Rd, Rb, Gg, Gs",
|
||||
rating=8
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gs",
|
||||
convert_to="Gs^Vc",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Re, Rd, Rb, Gg, Gs, Re, Rd, Rb, Gg, Gs",
|
||||
rating=7
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Rb",
|
||||
convert_to="Rb^Vda",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Re, Rd, Rb, Gg, Gs, Re, Rd, Rb, Gg, Gs, Dd",
|
||||
rating=6
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Re",
|
||||
convert_to="Re^Vda",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Re, Rd, Rb, Gg, Gs, Re, Rd, Rb, Gg, Gs, Dd",
|
||||
rating=6
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Rd",
|
||||
convert_to="Rd^Vda",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Re, Rd, Rb, Gg, Gs, Re, Rd, Rb, Gg, Gs, Dd, Dd",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Dd",
|
||||
convert_to="Dd^Vda",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Re, Rd, Rb, Gg, Gs, Re, Rd, Rb, Gg, Gs, Dd, Dd",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Ds",
|
||||
convert_to="Ds^Vda",
|
||||
adjacent_liked="Gg, Gs, Wwg, Wwg, Ds, Ds, Re, Rd, Rb, Gg, Gs, Re, Rd, Rb, Gg, Gs",
|
||||
rating=1
|
||||
},
|
||||
-- rough villages
|
||||
dr_village {
|
||||
terrain="Hh",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Re, Rd, Rb, Gg, Gs, Re, Rd, Rb, Gg, Gs, Hh, Hh^Fp, Hh^Uf, Mm",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh^Fp",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Re, Rd, Rb, Gg, Gs, Re, Rd, Rb, Gg, Gs, Hh, Hh^Fp, Hh^Uf, Mm",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh^Uf",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Re, Rd, Rb, Gg, Gs, Re, Rd, Rb, Gg, Gs, Hh, Hh^Fp, Hh^Uf, Mm",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Mm",
|
||||
convert_to="Mm^Vhh",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Re, Rd, Rb, Gg, Gs, Re, Rd, Rb, Gg, Gs, Hh, Hh^Fp, Hh^Uf, Mm",
|
||||
rating=3
|
||||
},
|
||||
-- cave villages
|
||||
dr_village {
|
||||
terrain="Uu",
|
||||
convert_to="Uu^Vu",
|
||||
adjacent_liked="Hh,Hh^Fp,Mm,Uu,Uh,Hh^Uf,Xu,Uu^Uf,Mm^Xm,Ww",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uh",
|
||||
convert_to="Uu^Vu",
|
||||
adjacent_liked="Hh,Hh^Fp,Mm,Uu,Uh,Hh^Uf,Xu,Uu^Uf,Mm^Xm,Ww",
|
||||
rating=4
|
||||
},
|
||||
-- water villages
|
||||
dr_village {
|
||||
terrain="Wwg",
|
||||
convert_to="Wwg^Vm",
|
||||
adjacent_liked="Wwg, Wwg, Ds",
|
||||
rating=1
|
||||
},
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gs, Gg, Re, Rb, Rd",
|
||||
min_distance=14,
|
||||
}
|
||||
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|
155
data/campaigns/World_Conquest/lua/map/generator/coral.lua
Normal file
|
@ -0,0 +1,155 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
local width = length
|
||||
if width % 2 == 1 then
|
||||
width = width + 1
|
||||
end
|
||||
|
||||
local res = {}
|
||||
res.border_size=0
|
||||
res.map_width=width
|
||||
res.map_height=length
|
||||
res.iterations=iterations
|
||||
res.hill_size=size
|
||||
res.villages=villages
|
||||
res.nplayers=players
|
||||
res.island_size=island
|
||||
res.castle_size=castle
|
||||
res.temperature_iterations=0
|
||||
--!? for some reason still can generate rivers with value 0
|
||||
res.max_lakes=1
|
||||
res.river_frequency=1
|
||||
res.roads=18
|
||||
res.road_windiness=4
|
||||
res.link_castles=true
|
||||
|
||||
res.height = {
|
||||
dr_height(955, "Uh"),
|
||||
dr_height(945, "Uu^Uf"),
|
||||
dr_height(900, "Uu"),
|
||||
dr_height(855, "Uh"),
|
||||
dr_height(845, "Uu^Uf"),
|
||||
dr_height(825, "Uu"),
|
||||
dr_height(775, "Xu"),
|
||||
dr_height(750, "Mm^Xm"),
|
||||
dr_height(700, "Mm"),
|
||||
dr_height(690, "Hh^Uf"),
|
||||
dr_height(660, "Hh^Fp"),
|
||||
dr_height(625, "Hh"),
|
||||
dr_height(540, "Gg"),
|
||||
dr_height(380, "Gs"),
|
||||
dr_height(310, "Wog"),-- just to avoid castle generation
|
||||
dr_height(280, "Ds"),
|
||||
dr_height(270, "Wwt"),
|
||||
dr_height(260, "Ds"),
|
||||
dr_height(250, "Wwrt"),
|
||||
dr_height(240, "Ds"),
|
||||
dr_height(230, "Wwt"),
|
||||
dr_height(220, "Ds"),
|
||||
dr_height(210, "Wwrt"),
|
||||
dr_height(200, "Ds"),
|
||||
dr_height(190, "Wwt"),
|
||||
dr_height(180, "Ds"),
|
||||
dr_height(170, "Wwt"),
|
||||
dr_height(160, "Ds"),
|
||||
dr_height(150, "Wwrt"),
|
||||
dr_height(140, "Ds"),
|
||||
dr_height(130, "Wwrt"),
|
||||
dr_height(120, "Ds"),
|
||||
dr_height(110, "Wwrt"),
|
||||
dr_height(100, "Ds"),
|
||||
dr_height(90, "Wwrt"),
|
||||
dr_height(80, "Dd"),-- just to avoid village generation
|
||||
dr_height(70, "Wwrt"),
|
||||
dr_height(60, "Dd"),
|
||||
dr_height(50, "Wwrt"),
|
||||
dr_height(40, "Dd"),
|
||||
dr_height(20, "Wwrt"),
|
||||
dr_height(1, "Wwt"),
|
||||
dr_height(0, "Wot"),
|
||||
}
|
||||
|
||||
res.road_cost = {
|
||||
dr_road("Gs", "Re", 10),
|
||||
dr_road("Gg", "Re", 9),
|
||||
dr_road("Re", "Re", 4),
|
||||
}
|
||||
res.village = {
|
||||
dr_village {
|
||||
terrain = "Gg",
|
||||
convert_to="Gg^Vd",
|
||||
adjacent_liked="Gg, Gs, Wwt, Wwrt, Re, Gg, Gs, Re, Gg, Gs, Hh, Mm, Hh^Fp",
|
||||
rating=8
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gs",
|
||||
convert_to="Gs^Vc",
|
||||
adjacent_liked="Gg, Gs, Wwt, Wwrt, Re, Gg, Gs, Re, Gg, Gs, Hh",
|
||||
rating=8
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Wog",
|
||||
convert_to="Gs^Vc",
|
||||
adjacent_liked="Gg, Gs, Wwt, Wwrt, Re, Gg, Gs, Re, Gg, Gs, Hh",
|
||||
rating=6
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Ds",
|
||||
convert_to="Ds^Vc",
|
||||
adjacent_liked="Gg, Gs, Wwt, Wwrt, Ds, Ds, Gs, Gs, Gs, Gs",
|
||||
rating=1
|
||||
},
|
||||
-- rough villages
|
||||
dr_village {
|
||||
terrain="Hh",
|
||||
convert_to="Hh^Vd",
|
||||
adjacent_liked="Gg, Gs, Wwt, Wwrt, Re, Gg, Gs, Re, Gg, Gs, Hh, Hh^Fp, Hh^Uf, Mm",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh^Fp",
|
||||
convert_to="Hh^Vd",
|
||||
adjacent_liked="Gg, Gs, Wwt, Wwrt, Re, Gg, Gs, Re, Gg, Gs, Hh, Hh^Fp, Hh^Uf, Mm",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh^Uf",
|
||||
convert_to="Hh^Vd",
|
||||
adjacent_liked="Gg, Gs, Wwt, Wwrt, Re, Gg, Gs, Re, Rd, Rb, Gg, Gs, Hh, Hh^Fp, Hh^Uf, Mm",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Mm",
|
||||
convert_to="Mm^Vd",
|
||||
adjacent_liked="Gg, Gs, Wwt, Wwrt, Re, Gg, Gs, Re, Rd, Rb, Gg, Gs, Hh, Hh^Fp, Hh^Uf, Mm",
|
||||
rating=3
|
||||
},
|
||||
-- cave villages
|
||||
dr_village {
|
||||
terrain="Uu",
|
||||
convert_to="Uu^Vu",
|
||||
adjacent_liked="Hh,Hh^Fp,Mm,Uu,Uh,Hh^Uf,Xu,Uu^Uf,Mm^Xm",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uh",
|
||||
convert_to="Uu^Vu",
|
||||
adjacent_liked="Hh,Hh^Fp,Mm,Uu,Uh,Hh^Uf,Xu,Uu^Uf,Mm^Xm",
|
||||
rating=4
|
||||
},
|
||||
-- water villages
|
||||
dr_village {
|
||||
terrain="Wwt",
|
||||
convert_to="Wwt^Vm",
|
||||
adjacent_liked="Wwt, Wwt, Wwrt",
|
||||
rating=1
|
||||
},
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gs,Gg",
|
||||
min_distance=14,
|
||||
}
|
||||
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|
140
data/campaigns/World_Conquest/lua/map/generator/delta.lua
Normal file
|
@ -0,0 +1,140 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
|
||||
local res = wct_generator_settings_arguments( length, villages, castle, iterations, size, players, island)
|
||||
res.max_lakes=10
|
||||
res.min_lake_height=150
|
||||
res.lake_size=125
|
||||
res.river_frequency=100
|
||||
res.temperature_size=4
|
||||
res.roads=10
|
||||
res.road_windiness=7
|
||||
|
||||
res.height = {
|
||||
dr_height(960, "Uue^Dr"),
|
||||
dr_height(910, "Uue"),
|
||||
dr_height(870, "Uue^Dr"),
|
||||
dr_height(800, "Uue"),
|
||||
dr_height(700, "Xuce"),
|
||||
dr_height(625, "Mm"),
|
||||
dr_height(475, "Hh"),
|
||||
dr_height(310, "Gg"),
|
||||
dr_height(300, "Ds"),
|
||||
dr_height(200, "Ww"),
|
||||
dr_height(0, "Wo"),
|
||||
}
|
||||
res.convert = {
|
||||
-- sand
|
||||
dr_convert(75, nil, nil, 200, "Ww,Wo", "Dd^Do"),
|
||||
dr_convert(180, nil, nil, 300, "Gg,Ds", "Dd"),
|
||||
dr_convert(500, nil, nil, 425, "Hh", "Hd"),
|
||||
dr_convert(nil, nil, 900, nil, "Gg", "Ds"),
|
||||
-- swamp
|
||||
dr_convert(nil, 200, 600, 900, "Gg", "Ss"),
|
||||
-- forest
|
||||
dr_convert(nil, nil, 240, 320, "Dd, Gs", "Ds^Ftd"),
|
||||
dr_convert(nil, nil, 350, 420, "Gg", "Gs^Fp"),
|
||||
-- fungus
|
||||
-- DR_CONVERT MIN_HT MAX_HT MIN_TMP MAX_TMP FROM TO
|
||||
dr_convert(825, 950, 500, 525, "Uue, Uue^Dr", "Uue^Uf"),
|
||||
dr_convert(825, 950, 550, 575, "Uue, Uue^Dr", "Uue^Uf"),
|
||||
dr_convert(825, 950, 600, 625, "Uue, Uue^Dr", "Uue^Uf"),
|
||||
-- lava
|
||||
dr_convert(800, nil, 850, nil, "Uue, Uue^Dr, Uue^Uf", "Ql"),
|
||||
}
|
||||
res.road_cost = {
|
||||
dr_road("Gg", "Re", 10),
|
||||
dr_road("Gs^Fp", "Re", 20),
|
||||
dr_road("Hh", "Re", 30),
|
||||
dr_road("Mm", "Re", 40),
|
||||
dr_road("Xuce", "Re", 80),
|
||||
dr_road("Uue", "Re", 10),
|
||||
dr_road("Uue^Dr", "Re", 40),
|
||||
dr_road("Ds", "Re", 25),
|
||||
dr_bridge("Ww", "Ww^Bw", "Ce", 50),
|
||||
dr_road("Re", "Re", 2),
|
||||
dr_road("Ce", "Ce", 2),
|
||||
dr_road_over_bridges("Ww^Bw", 2),
|
||||
}
|
||||
res.village = {
|
||||
dr_village {
|
||||
terrain = "Gg",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Ds^Ftd, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Hh, Gs^Fp",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ds",
|
||||
convert_to="Ds^Vda",
|
||||
adjacent_liked="Gg, Ds^Ftd, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Hh, Gs^Fp",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Dd",
|
||||
convert_to="Dd^Vda",
|
||||
adjacent_liked="Gg, Ds^Ftd, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Hh, Gs^Fp, Dd, Dd, Dd^Do",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ds^Ftd",
|
||||
convert_to="Ds^Vda",
|
||||
adjacent_liked="Gg, Ds^Ftd, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Hh, Gs^Fp, Dd, Dd, Dd^Do",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Dd^Do",
|
||||
convert_to="Ds^Vdt",
|
||||
adjacent_liked="Gg, Ds^Ftd, Ds^Ftd, Re, Re, Hh, Gs^Fp, Dd, Dd, Dd^Do, Dd^Do, Ds",
|
||||
rating=1
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uue",
|
||||
convert_to="Uue^Vu",
|
||||
adjacent_liked="Re,Hh,Mm,Uue,Uue^Dr,Xuce",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uue^Dr",
|
||||
convert_to="Uue^Vu",
|
||||
adjacent_liked="Re,Hh,Mm,Uue,Uue^Dr,Xuce",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gs^Fp",
|
||||
convert_to="Gg^Ve",
|
||||
adjacent_liked="Gg, Ds^Ftd, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Hh, Gs^Fp, Gs^Fp",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh",
|
||||
convert_to="Hh^Vh",
|
||||
adjacent_liked="Gg, Ds^Ftd, Hh, Hh, Mm, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Hh, Gs^Fp, Hh",
|
||||
rating=8
|
||||
},
|
||||
dr_village {
|
||||
terrain="Mm",
|
||||
convert_to="Mm^Vd",
|
||||
adjacent_liked="Gg, Ds^Ftd, Hh, Hh, Mm, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Hh, Gs^Fp, Hh",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ss",
|
||||
convert_to="Ss^Vhs",
|
||||
adjacent_liked="Gg, Ds^Ftd, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Hh, Gs^Fp",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ww",
|
||||
convert_to="Ww^Vm",
|
||||
adjacent_liked="Ww, Ww",
|
||||
rating=1
|
||||
},
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gg, Gs^Fp, Hh, Dd, Hd, Mm, Mm^Xm, Ds, Ss",
|
||||
min_distance=13,
|
||||
}
|
||||
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|
147
data/campaigns/World_Conquest/lua/map/generator/feudal.lua
Normal file
|
@ -0,0 +1,147 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
|
||||
local res = wct_generator_settings_arguments( length, villages, castle, iterations, size, players, island)
|
||||
res.max_lakes=40
|
||||
res.min_lake_height=450
|
||||
res.lake_size=35
|
||||
res.river_frequency=80
|
||||
res.temperature_size=size
|
||||
res.roads=20
|
||||
res.road_windiness=4
|
||||
|
||||
res.height = {
|
||||
dr_height(800, "Uu"),
|
||||
dr_height(750, "Xu"),
|
||||
dr_height(725, "Mm^Xm"),
|
||||
dr_height(690, "Mm"),
|
||||
dr_height(580, "Hh"),
|
||||
dr_height(200, "Gg"),
|
||||
dr_height(100, "Wot"), -- mark anti castle generation
|
||||
dr_height(35, "Ds"),
|
||||
dr_height(1, "Wwg"),
|
||||
dr_height(0, "Wog"),
|
||||
}
|
||||
res.convert = {
|
||||
wct_fix_river_into_ocean("g", 33),
|
||||
-- DR_CONVERT MIN_HT MAX_HT MIN_TMP MAX_TMP FROM TO
|
||||
-- low temperatures
|
||||
dr_convert(100, 999, 0, 400, "Ww", "Ai"),
|
||||
dr_convert(500, 999, 0, 420, "Ww", "Ai"),
|
||||
dr_convert(300, 999, 0, 410, "Gg", "Aa"),
|
||||
dr_convert(420, 999, 0, 425, "Gg", "Aa"),
|
||||
dr_convert(580, 999, 0, 430, "Hh", "Ha"),
|
||||
dr_convert(580, 999, 0, 435, "Mm", "Ms"),
|
||||
dr_convert(580, 999, 0, 440, "Mm^Xm", "Ms^Xm"),
|
||||
-- desert appears at extreme temperatures and medium altitude
|
||||
dr_convert(250, 530, 800, 999, "Gg", "Dd"),
|
||||
-- swamps
|
||||
dr_convert(450, 500, 500, 575, "Gg", "Ss"),
|
||||
dr_convert(300, 350, 475, 525, "Gg", "Ss"),
|
||||
dr_convert(100, 200, 450, 500, "Gg,Wot", "Ss"),
|
||||
|
||||
dr_temperature("Gg", 0, 460, "Gs"),
|
||||
dr_temperature("Hh", 470, 999, "Hhd"), -- mark for forst type
|
||||
}
|
||||
res.road_cost = {
|
||||
dr_road("Gg", "Re", 8),
|
||||
dr_road("Gs", "Re", 9),
|
||||
dr_road("Ss", "Ce", 20),
|
||||
dr_road("Hh", "Re", 20),
|
||||
dr_road("Hhd", "Re", 20),
|
||||
dr_road("Mm", "Re", 35),
|
||||
dr_road("Mm^Xm", "Re", 50),
|
||||
dr_road("Uu", "Re", 10),
|
||||
dr_road("Xu", "Re", 50),
|
||||
dr_road("Aa", "Coa", 20),
|
||||
dr_road("Ha", "Re", 20),
|
||||
dr_road("Dd", "Cd", 20),
|
||||
dr_road("Hd", "Re", 20),
|
||||
dr_bridge("Ww", "Ww^Bw", "Ce", 45),
|
||||
dr_road("Re", "Re", 2),
|
||||
dr_road_over_bridges("Ww^Bw", 2),
|
||||
dr_road("Ch", "Ch", 2),
|
||||
dr_road("Ce", "Ce", 2),
|
||||
dr_road("Cd", "Cd", 2),
|
||||
dr_road("Coa", "Coa", 2),
|
||||
}
|
||||
res.village = {
|
||||
dr_village {
|
||||
terrain = "Gg",
|
||||
convert_to="Gg^Vc",
|
||||
adjacent_liked="Gg, Gg, Gg, Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Hh, Hhd",
|
||||
rating=8
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gs",
|
||||
convert_to="Gg^Vc",
|
||||
adjacent_liked="Gg, Gg, Gs, Gs, Gs, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Hh, Hhd",
|
||||
rating=8
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ds",
|
||||
convert_to="Ds^Vda",
|
||||
adjacent_liked="Gg, Ds, Ds, Wwg, Wwg, Wwg, Ww, Hhd",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uu",
|
||||
convert_to="Uu^Vud",
|
||||
adjacent_liked="Re,Hh,Hhd,Mm,Uu,Uu,Uu,Xu",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gs, Gs, Gs, Gs, Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Hh, Hh, Hhd",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hhd",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Gg, Gg, Gg, Gs, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Hhd, Hhd, Hhd",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Mm",
|
||||
convert_to="Mm^Vhh",
|
||||
adjacent_liked="Gg, Gg, Gg, Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Hh, Hh, Hhd, Hhd",
|
||||
rating=3
|
||||
},
|
||||
-- villages in snow
|
||||
dr_village {
|
||||
terrain="Aa",
|
||||
convert_to="Aa^Voa",
|
||||
adjacent_liked="Gs, Gs, Aa, Aa, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Hh, Ha, Ha",
|
||||
rating=3
|
||||
},
|
||||
-- villages in dessert
|
||||
dr_village {
|
||||
terrain="Dd",
|
||||
convert_to="Dd^Vda",
|
||||
adjacent_liked="Gg, Gg, Dd, Dd, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Hhd, Hhd",
|
||||
rating=3
|
||||
},
|
||||
-- swamp villages
|
||||
dr_village {
|
||||
terrain="Ss",
|
||||
convert_to="Ss^Vhs",
|
||||
adjacent_liked="Gg, Gg, Gs, Gs, Ss, Ss, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Hh, Hh, Hhd, Hhd",
|
||||
rating=2
|
||||
},
|
||||
-- mermen villages - give them low chance of appearing
|
||||
dr_village {
|
||||
terrain="Wwg",
|
||||
convert_to="Wwg^Vm",
|
||||
adjacent_liked="Wwg, Wwg",
|
||||
rating=1
|
||||
},
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gs, Gg, Hh, Hhd, Mm, Aa, Ha",
|
||||
min_distance=13,
|
||||
}
|
||||
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|
226
data/campaigns/World_Conquest/lua/map/generator/industrial.lua
Normal file
|
@ -0,0 +1,226 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
|
||||
local res = wct_generator_settings_arguments( length, villages, castle, iterations, size, players, island)
|
||||
res.max_lakes=115
|
||||
res.min_lake_height=320
|
||||
res.lake_size=60
|
||||
res.river_frequency=95
|
||||
res.temperature_size=7
|
||||
res.roads=11
|
||||
res.road_windiness=8
|
||||
|
||||
res.height = {
|
||||
-- list of common terrain types which come in at different heights, from highest to lowest
|
||||
dr_height(950, "Uh"),
|
||||
dr_height(910, "Uu"),
|
||||
dr_height(870, "Uh"),
|
||||
dr_height(820, "Uu"),
|
||||
dr_height(780, "Xu"),
|
||||
dr_height(765, "Mm^Xm"),
|
||||
dr_height(725, "Mm"),
|
||||
dr_height(715, "Hh"),
|
||||
dr_height(710, "Hh^Fp"),
|
||||
dr_height(685, "Hh"),
|
||||
dr_height(675, "Hh^Uf"),
|
||||
dr_height(650, "Hh"),
|
||||
dr_height(645, "Hh^Fp"),
|
||||
dr_height(610, "Hh"),
|
||||
dr_height(600, "Gg"),
|
||||
dr_height(590, "Hh^Fp"),
|
||||
dr_height(580, "Gg"),
|
||||
dr_height(570, "Gs^Fp"),
|
||||
dr_height(425, "Gg"),
|
||||
dr_height(420, "Hh^Fp"),
|
||||
dr_height(410, "Gg"),
|
||||
dr_height(400, "Mm"),
|
||||
dr_height(395, "Gs^Uf"),
|
||||
dr_height(380, "Ss"),
|
||||
dr_height(375, "Gs^Uf"),
|
||||
dr_height(360, "Gg"),
|
||||
dr_height(340, "Hh^Fp"),
|
||||
dr_height(320, "Gg"),
|
||||
dr_height(300, "Gs^Fp"),
|
||||
dr_height(260, "Gg"),
|
||||
dr_height(240, "Ss"),
|
||||
dr_height(220, "Gs^Fp"),
|
||||
dr_height(200, "Hh^Fp"),
|
||||
dr_height(125, "Gg"),
|
||||
dr_height(50, "Ds"),
|
||||
dr_height(1, "Wwt"),
|
||||
dr_height(0, "Wot"),
|
||||
}
|
||||
res.convert = {
|
||||
wct_fix_river_into_ocean("t", 46),
|
||||
|
||||
-- DR_CONVERT MIN_HT MAX_HT MIN_TMP MAX_TMP FROM TO
|
||||
-- low temperatures
|
||||
dr_convert(80, 999, 0, 375, "Gg, Gs^Uf", "Aa"),
|
||||
dr_convert(250, 999, 0, 375, "Ss", "Ai"),
|
||||
dr_convert(80, 999, 370, 425, "Gg", "Gs"),
|
||||
dr_convert(80, 999, 0, 375, "Gs^Fp", "Aa^Fpa"),
|
||||
dr_convert(80, 999, 375, 425, "Gs^Fp", "Gs^Fmw"),
|
||||
dr_convert(0, 999, 0, 400, "Hh^Fp, Hh^Uf", "Ha^Fpa"),
|
||||
dr_convert(80, 999, 400, 450, "Hh^Fp", "Hh^Fmw"),
|
||||
dr_convert(0, 999, 0, 425, "Hh", "Ha"),
|
||||
dr_convert(0, 999, 0, 450, "Mm", "Ms"),
|
||||
dr_convert(750, 999, 0, 460, "Mm^Xm", "Ms^Xm"),
|
||||
-- fungus
|
||||
dr_convert(850, 950, 500, 525, "Uu, Uh", "Uu^Uf"),
|
||||
dr_convert(850, 950, 550, 575, "Uu, Uh", "Uu^Uf"),
|
||||
dr_convert(850, 950, 600, 625, "Uu, Uh", "Uu^Uf"),
|
||||
-- high temperatures
|
||||
dr_convert(825, 999, 850, 999, "Uu, Uh, Uu^Uf", "Ql"),
|
||||
dr_convert(0, 999, 800, 999, "Gg", "Dd"),
|
||||
dr_convert(250, 999, 800, 999, "Ss", "Dd^Do"),
|
||||
dr_convert(80, 999, 750, 800, "Gg", "Gs"),
|
||||
dr_convert(80, 999, 730, 760, "Gs^Fp", "Gs^Fet"),
|
||||
-- moderate temperatures
|
||||
dr_convert(0, 999, 450, 575, "Hh^Fp", "Hh^Fmf"),
|
||||
dr_convert(0, 999, 430, 575, "Gs^Fp", "Gg^Fmf"),
|
||||
dr_convert(0, 999, 575, 725, "Hh^Fp", "Hh^Fms"),
|
||||
dr_convert(0, 999, 575, 725, "Gs^Fp", "Gg^Fms"),
|
||||
}
|
||||
res.road_cost = {
|
||||
dr_road("Gg", "Urb", 10),
|
||||
dr_road("Gs^Fp", "Urb", 20),
|
||||
dr_road("Gs^Fmw", "Urb", 20),
|
||||
dr_road("Gs^Fet", "Urb", 20),
|
||||
dr_road("Gg^Fmf", "Urb", 20),
|
||||
dr_road("Gg^Fms", "Urb", 20),
|
||||
dr_road("Hh", "Urb", 25),
|
||||
dr_road("Hh^Fp", "Urb", 30),
|
||||
dr_road("Hh^Fmf", "Urb", 30),
|
||||
dr_road("Hh^Fmw", "Urb", 30),
|
||||
dr_road("Hh^Fms", "Urb", 30),
|
||||
dr_road("Hh^Uf", "Urb", 25),
|
||||
dr_road("Mm", "Urb", 40),
|
||||
dr_road("Mm^Xm", "Urb", 75),
|
||||
dr_bridge("Ql", "Ql^Bs", "Urb", 100),
|
||||
dr_bridge("Qxu", "Qxu^Bs", "Urb", 100),
|
||||
dr_road("Uu", "Urb", 10),
|
||||
dr_road("Uh", "Urb", 35),
|
||||
dr_road("Xu", "Urb", 80),
|
||||
dr_road("Aa", "Urb", 15),
|
||||
dr_road("Ha", "Urb", 20),
|
||||
dr_road("Ha^Fpa", "Urb", 25),
|
||||
dr_road("Aa^Fpa", "Urb", 20),
|
||||
dr_bridge("Ww", "Ww^Bcx", "Ce", 50),
|
||||
dr_road("Urb", "Urb", 2),
|
||||
dr_road_over_bridges("Ww^Bcx", 2),
|
||||
dr_road("Ch", "Ch", 2),
|
||||
dr_road("Ce", "Ce", 2),
|
||||
dr_road("Dd", "Urb", 25),
|
||||
dr_road("Ds", "Urb", 35),
|
||||
}
|
||||
res.village = {
|
||||
dr_village {
|
||||
terrain = "Gg",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Urb, Urb, Urb, Urb, Hh, Gs^Fp, Gg^Fms",
|
||||
rating=8
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gs",
|
||||
convert_to="Gs^Vh",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Urb, Urb, Urb, Urb, Hh, Ha, Gs^Fp, Gg^Fms",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ds",
|
||||
convert_to="Ds^Vda",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Urb, Urb, Urb, Urb, Hh, Gs^Fp",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Dd",
|
||||
convert_to="Dd^Vda",
|
||||
adjacent_liked="Gg, Gs, Dd, Dd, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Ww, Ww, Urb, Urb, Hh, Gs^Fp, Mm",
|
||||
rating=4
|
||||
},
|
||||
-- villages in cave are orcish
|
||||
dr_village {
|
||||
terrain="Uu",
|
||||
convert_to="Uu^Vo",
|
||||
adjacent_liked="Urb,Hh,Mm,Uu,Uh,Xu,Mm^Xm,Uu^Uf,Uu,Uh,Ww,Ww",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uu^Uf",
|
||||
convert_to="Uh^Vo",
|
||||
adjacent_liked="Urb,Hh,Mm,Uu,Uh,Xu,Mm^Xm,Uu^Uf,Uu,Uh,Ww,Ww",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uh",
|
||||
convert_to="Uu^Vo",
|
||||
adjacent_liked="Urb,Hh,Mm,Uu,Uh,Xu,Mm^Xm,Uu^Uf,Uu,Uh,Ww,Ww",
|
||||
rating=5
|
||||
},
|
||||
-- villages in forest
|
||||
dr_village {
|
||||
terrain="Gs^Fp",
|
||||
convert_to="Gs^Vh",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Urb, Urb, Urb, Urb, Hh, Gs^Fp, Gs^Fp, Gg^Fms",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gg^Fms",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Gs, Gg, Ww, Ww, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Urb, Urb, Urb, Urb, Hh, Gs^Fp, Gg^Fms, Gg^Fms",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh",
|
||||
convert_to="Hh^Vh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Urb, Urb, Urb, Urb, Gg^Ve, Gg^Vh, Hh, Gs^Fp",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Mm",
|
||||
convert_to="Mm^Vd",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Urb, Urb, Urb, Urb, Gg^Ve, Gg^Vh, Hh, Gs^Fp",
|
||||
rating=3
|
||||
},
|
||||
-- villages in snow
|
||||
dr_village {
|
||||
terrain="Aa",
|
||||
convert_to="Aa^Vha",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Urb, Urb, Urb, Urb, Gg^Ve, Gg^Vh, Hh, Gs^Fp",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Aa^Fpa",
|
||||
convert_to="Aa^Vha",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Urb, Urb, Urb, Urb, Gg^Ve, Gg^Vh, Hh, Gs^Fp",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ha",
|
||||
convert_to="Ha^Vha",
|
||||
adjacent_liked="Gg, Gs, Gs, Ww, Ww, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Urb, Urb, Urb, Urb, Hh, Ha, Mm, Gs^Fp",
|
||||
rating=3
|
||||
},
|
||||
-- swamp villages
|
||||
dr_village {
|
||||
terrain="Ss",
|
||||
convert_to="Ss^Vhs",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bcx|, Ww^Bcx/, Ww^Bcx\\, Urb, Urb, Urb, Urb, Gg^Ve, Gg^Vh, Hh, Gs^Fp",
|
||||
rating=2
|
||||
},
|
||||
-- mermen villages
|
||||
dr_village {
|
||||
terrain="Wwt",
|
||||
convert_to="Wwt^Vm",
|
||||
adjacent_liked="Wwt, Wwt",
|
||||
rating=1
|
||||
},
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gs, Gg, Hh, Ha, Hh^Uf, Gs^Uf, Ss, Dd, Aa",
|
||||
min_distance=16,
|
||||
}
|
||||
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|
202
data/campaigns/World_Conquest/lua/map/generator/maritime.lua
Normal file
|
@ -0,0 +1,202 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
|
||||
local res = wct_generator_settings_arguments( length, villages, castle, iterations, size, players, island)
|
||||
res.max_lakes=90
|
||||
res.min_lake_height=250
|
||||
res.lake_size=60
|
||||
res.river_frequency=100
|
||||
res.temperature_size=7
|
||||
res.roads=25
|
||||
res.road_windiness=2
|
||||
|
||||
res.height = {
|
||||
-- list of common terrain types which come in at different heights, from highest to lowest
|
||||
dr_height(910, "Uh"),
|
||||
dr_height(820, "Uu"),
|
||||
dr_height(780, "Xu"),
|
||||
dr_height(765, "Mm^Xm"),
|
||||
dr_height(725, "Mm"),
|
||||
dr_height(610, "Hh"),
|
||||
dr_height(600, "Gg"),
|
||||
dr_height(590, "Hh^Fp"),
|
||||
dr_height(580, "Gg"),
|
||||
dr_height(570, "Gs^Fp"),
|
||||
dr_height(410, "Gg"),
|
||||
dr_height(400, "Mm"),
|
||||
dr_height(360, "Gg"),
|
||||
dr_height(340, "Hh^Fp"),
|
||||
dr_height(320, "Gg"),
|
||||
dr_height(300, "Gs^Fp"),
|
||||
dr_height(240, "Gg"),
|
||||
dr_height(220, "Gs^Fp"),
|
||||
dr_height(200, "Hh^Fp"),
|
||||
dr_height(180, "Hh"),
|
||||
dr_height(100, "Gg"),
|
||||
dr_height(30, "Ds"),
|
||||
dr_height(1, "Wwg"),
|
||||
dr_height(0, "Wog"),
|
||||
}
|
||||
res.convert = {
|
||||
wct_fix_river_into_ocean("g", 29),
|
||||
-- DR_CONVERT MIN_HT MAX_HT MIN_TMP MAX_TMP FROM TO
|
||||
-- low temperatures
|
||||
dr_convert(50, 999, 0, 270, "Ww, Wo", "Ai"),
|
||||
dr_convert(350, 999, 0, 320, "Gg", "Aa"),
|
||||
dr_convert(330, 999, 320, 370, "Gg", "Gd"),
|
||||
dr_convert(100, 999, 370, 475, "Gg", "Gs"),
|
||||
dr_convert(350, 999, 0, 310, "Gs^Fp", "Aa^Fpa"),
|
||||
dr_convert(350, 999, 0, 345, "Hh", "Ha"),
|
||||
dr_convert(350, 999, 0, 335, "Hh^Fp", "Ha^Fpa"),
|
||||
dr_convert(350, 999, 0, 370, "Mm", "Ms"),
|
||||
dr_convert(350, 999, 0, 390, "Mm^Xm", "Ms^Xm"),
|
||||
-- swamp appears on low land, at mod temp
|
||||
dr_convert(0, 200, 400, 700, "Gg", "Ss"),
|
||||
-- pine appears at low temperatures
|
||||
dr_convert(150, 999, 320, 420, "Gg", "Gs^Fp"),
|
||||
dr_convert(150, 999, 320, 420, "Hh", "Hh^Fp"),
|
||||
-- decidius appears at mod temperatures with some heigh
|
||||
dr_convert(300, 999, 510, 540, "Gg,Gs", "Gg^Fds"),
|
||||
dr_convert(300, 999, 510, 540, "Hh", "Hh^Fds"),
|
||||
-- fungus appears at med temp and high
|
||||
dr_convert(825, 950, 500, 525, "Uu, Uh", "Uu^Uf"),
|
||||
dr_convert(825, 950, 550, 575, "Uu, Uh", "Uu^Uf"),
|
||||
dr_convert(825, 950, 600, 625, "Uu, Uh", "Uu^Uf"),
|
||||
-- high temperatures
|
||||
dr_convert(800, 999, 850, 999, "Uu, Uh, Uu^Uf", "Ql"),
|
||||
dr_convert(260, 999, 800, 999, "Gg", "Dd"),
|
||||
dr_convert(230, 999, 750, 999, "Gg", "Gd"),
|
||||
dr_convert(100, 999, 650, 999, "Gg", "Gs"),
|
||||
dr_convert(460, 630, 800, 999, "Ds, Hh", "Hd"),
|
||||
|
||||
-- DR_TEMPERATURE FROM MIN MAX TO),
|
||||
-- convert forest at different temperatures
|
||||
dr_temperature("Gs^Fp", 420, 475, "Gs^Fdf"),
|
||||
dr_temperature("Hh^Fp", 420, 510, "Hh^Fmf"),
|
||||
dr_temperature("Gs^Fp", 475, 510, "Gg^Fdf"),
|
||||
dr_temperature("Gs^Fp", 510, 540, "Gg^Fds"),
|
||||
dr_temperature("Hh^Fp", 510, 540, "Hh^Fds"),
|
||||
dr_temperature("Gs^Fp", 540, 650, "Gg^Ftr"),
|
||||
dr_temperature("Hh^Fp", 540, 650, "Hh^Fms"),
|
||||
}
|
||||
res.road_cost = {
|
||||
wct_generator_road_cost_classic(),
|
||||
dr_road("Gs", "Re", 10),
|
||||
dr_road("Gd", "Re", 10),
|
||||
dr_road("Gg^Fds", "Re", 20),
|
||||
dr_road("Gg^Ftr", "Re", 20),
|
||||
dr_road("Gg^Fdf", "Re", 20),
|
||||
dr_road("Hh^Fmf", "Re", 20),
|
||||
dr_road("Hh^Ft", "Re", 30),
|
||||
dr_road("Hh^Fp", "Re", 30),
|
||||
dr_road("Hh^Fds", "Re", 20),
|
||||
dr_road("Hh^Fms", "Re", 20),
|
||||
dr_road("Gs^Ft", "Re", 30),
|
||||
dr_road("Ds", "Re", 20),
|
||||
dr_bridge("Ww", "Ww^Bsb", "Chw", 35),
|
||||
dr_road("Chw", "Chw", 2),
|
||||
dr_road_over_bridges("Ww^Bsb", 2),
|
||||
}
|
||||
res.village = {
|
||||
dr_village {
|
||||
terrain = "Gg",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Re, Re, Re, Re, Hh, Gs, Gg",
|
||||
rating=8
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gs",
|
||||
convert_to="Gs^Vh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Re, Re, Re, Re, Hh, Gs, Gg, Gd, Gd, Gs, Gs",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gd",
|
||||
convert_to="Gd^Vc",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Re, Re, Re, Re, Hh, Gs, Gd, Gd, Gs, Gs, Gd",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ds",
|
||||
convert_to="Dd^Vda",
|
||||
adjacent_liked="Gg, Gs, Gd, Wwg, Wwg, Wwg, Re, Re, Hh, Ch, Wog,",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uu",
|
||||
convert_to="Uu^Vud",
|
||||
adjacent_liked="Re,Hh,Mm,Uu,Uh,Xu",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uh",
|
||||
convert_to="Uu^Vu",
|
||||
adjacent_liked="Re,Hh,Mm,Uu,Uh,Xu",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gg^Fds",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Re, Re, Re, Re, Hh, Gs, Gg, Gg^Fds",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gs^Fp",
|
||||
convert_to="Gs^Vh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Re, Re, Re, Re, Hh, Gs, Gg, Gd, Gd, Gs, Gs, Gs^Fp",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Re, Re, Re, Re, Hh, Gs, Gg, Gd, Gd, Gs, Gs, Gs^Fp",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh^Fp",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Re, Re, Re, Re, Hh, Gs, Gg, Gd, Gd, Gs, Gs, Gs^Fp",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Mm",
|
||||
convert_to="Mm^Vhh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bsb|, Ww^Bsb/, Ww^Bsb\\, Rr, Rr, Re, Re, Gg^Ve, Gg^Vh, Hh, Gs^Fp",
|
||||
rating=4
|
||||
},
|
||||
-- villages in snow
|
||||
dr_village {
|
||||
terrain="Aa",
|
||||
convert_to="Aa^Vha",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bsb|, Ww^Bsb/, Ww^Bsb\\, Rr, Rr, Re, Re, Gg^Ve, Gg^Vh, Hh, Gs^Fp",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Aa^Fpa",
|
||||
convert_to="Aa^Vea",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bsb|, Ww^Bsb/, Ww^Bsb\\, Rr, Rr, Re, Re, Gg^Ve, Gg^Vh, Hh, Gs^Fp",
|
||||
rating=3
|
||||
},
|
||||
-- swamp villages
|
||||
dr_village {
|
||||
terrain="Ss",
|
||||
convert_to="Ss^Vhs",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bsb|, Ww^Bsb/, Ww^Bsb\\, Rr, Rr, Re, Re, Gg^Ve, Gg^Vh, Hh, Gs^Fp",
|
||||
rating=2
|
||||
},
|
||||
-- mermen villages - give them low chance of appearing
|
||||
dr_village {
|
||||
terrain="Wwg",
|
||||
convert_to="Wwg^Vm",
|
||||
adjacent_liked="Wwg, Wwg, Ch, Ss, Ds, Ds",
|
||||
rating=1
|
||||
},
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gs, Gg, Gd, Gs^Fp, Gg^Ft, Gg^Fds, Gg^Ftr, Hh, Hh^Fp, Hh^Ft, Hh^Fds, Hh^Fms, Ha^Fpa, Ha, Hh^Fmf, Gg^Fdf",
|
||||
min_distance=15,
|
||||
}
|
||||
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|
211
data/campaigns/World_Conquest/lua/map/generator/paradise.lua
Normal file
|
@ -0,0 +1,211 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
|
||||
local res = wct_generator_settings_arguments( length, villages, castle, iterations, size, players, island)
|
||||
res.max_lakes=5
|
||||
res.min_lake_height=900
|
||||
res.lake_size=1
|
||||
res.river_frequency=1
|
||||
res.temperature_size=size
|
||||
res.roads=25
|
||||
res.road_windiness=4
|
||||
|
||||
res.height = {
|
||||
-- list of common terrain types which come in at different heights, from highest to lowest
|
||||
dr_height(990, "Rr"),
|
||||
dr_height(980, "Ww"),
|
||||
dr_height(960, "Rr"),
|
||||
dr_height(950, "Xos"),
|
||||
dr_height(940, "Rr^Fet"),
|
||||
dr_height(910, "Xos"),
|
||||
dr_height(870, "Rr"),
|
||||
dr_height(855, "Rr^Fet"),
|
||||
dr_height(850, "Ww"),
|
||||
dr_height(840, "Hh^Fp"),
|
||||
dr_height(830, "Hh"),
|
||||
dr_height(820, "Mm"),
|
||||
dr_height(810, "Gg"),
|
||||
dr_height(785, "Gg^Fp"),
|
||||
dr_height(775, "Gg"),
|
||||
dr_height(760, "Hh^Fp"),
|
||||
dr_height(750, "Gg"),
|
||||
dr_height(730, "Hh"),
|
||||
dr_height(720, "Mm"),
|
||||
dr_height(685, "Gg"),
|
||||
dr_height(670, "Gg^Fp"),
|
||||
dr_height(620, "Gg"),
|
||||
dr_height(610, "Hh^Fp"),
|
||||
dr_height(560, "Gg"),
|
||||
dr_height(550, "Hh"),
|
||||
dr_height(500, "Gg"),
|
||||
dr_height(485, "Mm"),
|
||||
dr_height(450, "Hh"),
|
||||
dr_height(400, "Hh^Fp"),
|
||||
dr_height(350, "Gg^Fp"),
|
||||
dr_height(230, "Gg"),
|
||||
dr_height(220, "Gg^Fp"),
|
||||
dr_height(85, "Gg"),
|
||||
dr_height(30, "Ds"),
|
||||
dr_height(20, "Ww"),
|
||||
dr_height(17, "Wwr"),
|
||||
dr_height(1, "Ww"),
|
||||
dr_height(0, "Wo"),
|
||||
}
|
||||
res.convert = {
|
||||
-- DR_CONVERT MIN_HT MAX_HT MIN_TMP MAX_TMP FROM TO
|
||||
dr_convert(70, 150, 10, 300, "Gg", "Ss"),
|
||||
dr_convert(550, 680, 350, 370, "Gg", "Hh^Uf"),
|
||||
dr_convert(550, 680, 620, 640, "Gg", "Hh^Uf"),
|
||||
|
||||
-- DR_TEMPERATURE FROM MIN MAX TO),
|
||||
-- convert forest at different temperatures
|
||||
dr_temperature("Gs^Fp", 700, 990, "Gg^Ft"),
|
||||
dr_temperature("Hh^Fp", 700, 990, "Hh^Ft"),
|
||||
dr_temperature("Gg^Fp", 400, 700, "Gg^Ftp"),
|
||||
dr_temperature("Hh^Fp", 400, 700, "Hh^Ftp"),
|
||||
dr_temperature("Gg^Fp", 250, 400, "Gg^Ftr"),
|
||||
dr_temperature("Hh^Fp", 250, 400, "Hh^Ftd"),
|
||||
dr_temperature("Gg^Fp", 125, 250, "Gg^Fds"),
|
||||
dr_temperature("Hh^Fp", 125, 250, "Hh^Fds"),
|
||||
dr_temperature("Gg^Fp", 10, 125, "Gg^Fms"),
|
||||
dr_temperature("Hh^Fp", 10, 125, "Hh^Fms"),
|
||||
}
|
||||
res.road_cost = {
|
||||
-- try to conect citadels
|
||||
dr_bridge("Rr", "Ww^Bsb", "Rr", 1),
|
||||
dr_road("Ww^Bsb", "Ww^Bsb", 3),
|
||||
dr_road("Rr^Fet", "Rr^Fet", 1),
|
||||
dr_road("Xos", "Xos", 1),
|
||||
-- flat
|
||||
dr_road("Ch", "Ch", 2),
|
||||
dr_road("Re", "Re", 2),
|
||||
dr_road("Gg", "Re", 10),
|
||||
-- forest
|
||||
dr_road("Gg^Ftp", "Re", 20),
|
||||
dr_road("Gg^Fms", "Re", 20),
|
||||
dr_road("Gg^Fds", "Re", 20),
|
||||
dr_road("Gg^Ft", "Re", 20),
|
||||
dr_road("Gg^Ftr", "Re", 20),
|
||||
dr_road("Hh^Ftp", "Re", 20),
|
||||
dr_road("Hh^Fms", "Re", 20),
|
||||
dr_road("Hh^Fds", "Re", 20),
|
||||
dr_road("Hh^Ft", "Re", 20),
|
||||
dr_road("Hh^Ftd", "Re", 20),
|
||||
-- rough
|
||||
dr_road("Hh", "Re", 20),
|
||||
dr_road("Mm", "Re", 40),
|
||||
dr_road("Ds", "Re", 25),
|
||||
dr_bridge("Ww", "Ww^Bw", "Ch", 50),
|
||||
}
|
||||
res.village = {
|
||||
dr_village {
|
||||
terrain = "Rr",
|
||||
convert_to="Rr^Vhc",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Rr, Rr, Re, Re, Rr^Fet, Gg^Vh, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=10
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gg",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Rr, Rr, Re, Re, Rr^Fet, Gg^Vh, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Hh^Fms",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Rr, Rr, Re, Re, Rr^Fet, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Hh^Fds",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Rr, Rr, Re, Re, Rr^Fet, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Hh^Ftp",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Rr, Rr, Re, Re, Rr^Fet, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Hh^Ft",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Rr, Rr, Re, Re, Rr^Fet, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Hh^Ftd",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Rr, Rr, Re, Re, Rr^Fet, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ds",
|
||||
convert_to="Ds^Vc",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Rr, Rr, Re, Re, Hh, Rr^Fet, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gg^Fms",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Rr, Rr, Re, Re, Rr^Fet, Gg^Vh, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gg^Fds",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Rr, Rr, Re, Re, Rr^Fet, Gg^Vh, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gg^Ft",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Rr, Rr, Re, Re, Rr^Fet, Gg^Vh, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gg^Ftp",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Rr, Rr, Re, Re, Rr^Fet, Gg^Vh, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gg^Ftr",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Rr, Rr, Re, Re, Rr^Fet, Gg^Vh, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Rr, Rr, Re, Re, Rr^Fet, Gg^Vh, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Mm",
|
||||
convert_to="Mm^Vhh",
|
||||
adjacent_liked="Gg, Gg^Ftr, Gg^Ftp, Gg^Fds, Gg^Fms, Gg^Ftd, Gg^Ft, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Rr, Rr, Re, Re, Rr^Fet, Gg^Vh, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Xos",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ss",
|
||||
convert_to="Ss^Vhs",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Rr, Rr, Re, Re, Gg^Ve, Gg^Vh, Hh, Gs^Fp",
|
||||
rating=1
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ww",
|
||||
convert_to="Ww^Vm",
|
||||
adjacent_liked="Ww, Ww",
|
||||
rating=1
|
||||
},
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gg, Gg^Fp, Gg^Ft, Gg^Ftr, Gg^Ftp, Gg^Ftd, Gg^Fds, Gg^Fms, Hh, Hh^Ft, Hh^Ftr, Hh^Ftp, Hh^Ftd, Hh^Fds, Hh^Fms, Mm, Hh^Fp",
|
||||
min_distance=14,
|
||||
}
|
||||
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|
210
data/campaigns/World_Conquest/lua/map/generator/podzol.lua
Normal file
|
@ -0,0 +1,210 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
|
||||
local res = wct_generator_settings_arguments( length, villages, castle, iterations, size, players, island)
|
||||
res.max_lakes=30
|
||||
res.min_lake_height=170
|
||||
res.lake_size=75
|
||||
res.river_frequency=80
|
||||
res.temperature_size=9
|
||||
res.roads=11
|
||||
res.road_windiness=8
|
||||
|
||||
res.height = {
|
||||
dr_height(990, "Qxu"),
|
||||
dr_height(960, "Uu"),
|
||||
dr_height(900, "Uh"),
|
||||
dr_height(825, "Uu"),
|
||||
dr_height(775, "Xu"),
|
||||
dr_height(750, "Mm^Xm"),
|
||||
dr_height(720, "Mm"),
|
||||
dr_height(670, "Hhd"),
|
||||
dr_height(650, "Hh^Fp"),
|
||||
dr_height(630, "Hhd^Uf"),
|
||||
dr_height(610, "Gll^Fp"),
|
||||
dr_height(590, "Gll^Uf"),
|
||||
dr_height(580, "Hhd"),
|
||||
dr_height(400, "Gll"),
|
||||
dr_height(395, "Hh"),
|
||||
dr_height(360, "Ss"),
|
||||
dr_height(340, "Gll^Ftr"),
|
||||
dr_height(330, "Hh"),
|
||||
dr_height(320, "Hh^Uf"),
|
||||
dr_height(300, "Hh^Fp"),
|
||||
dr_height(280, "Ss"),
|
||||
dr_height(270, "Hh"),
|
||||
dr_height(250, "Gll^Fp"),
|
||||
dr_height(225, "Gll^Uf"),
|
||||
dr_height(175, "Gll"),
|
||||
dr_height(70, "Ds"),
|
||||
dr_height(65, "Wwrt"),
|
||||
dr_height(35, "Wwt"),
|
||||
dr_height(30, "Wwrt"),
|
||||
dr_height(1, "Wwt"),
|
||||
dr_height(0, "Wot"),
|
||||
}
|
||||
res.convert = {
|
||||
wct_fix_river_into_ocean("t", 65),
|
||||
|
||||
-- DR_CONVERT MIN_HT MAX_HT MIN_TMP MAX_TMP FROM TO
|
||||
dr_convert(360, 999, 10, 400, "Ww", "Ai"),
|
||||
dr_convert(475, 750, 10, 415, "Gll^Fp", "Aa^Fpa"),
|
||||
dr_convert(450, 750, 10, 425, "Gll", "Aa"),
|
||||
dr_convert(410, 750, 10, 465, "Gll,Gll^Uf", "Gd"),
|
||||
dr_convert(650, 750, 10, 540, "Hh,Hhd", "Ha"),
|
||||
dr_convert(650, 750, 10, 510, "Hh^Fp", "Ha^Fpa"),
|
||||
dr_convert(650, 750, 10, 415, "Hh^Uf,Hhd^Uf", "Ha^Uf"),
|
||||
dr_convert(375, 750, 10, 390, "Ss", "Ai"),
|
||||
dr_convert(450, 750, 650, 675, "Gll", "Gll^Fet"),
|
||||
dr_convert(100, 300, 800, 850, "Gll", "Gll^Em"),
|
||||
dr_convert(400, 750, 680, 700, "Gll", "Gll^Efm"),
|
||||
dr_convert(475, 505, 725, 750, "Gll", "Ce"),
|
||||
dr_convert(585, 595, 10, 440, "Aa,Gll^Uf", "Ms"),
|
||||
dr_convert(575, 585, 10, 440, "Aa", "Ha"),
|
||||
dr_convert(475, 600, 870, 900, "Gll,Gll^Uf", "Ql"),
|
||||
|
||||
-- DR_TEMPERATURE FROM MIN MAX TO),
|
||||
dr_temperature("Mm", 10, 570, "Ms"),
|
||||
dr_temperature("Mm^Xm", 10, 585, "Ms^Xm"),
|
||||
dr_temperature("Ds", 870, 900, "Ds^Edpp"),
|
||||
dr_temperature("Uu", 100, 300, "Ai"),
|
||||
dr_temperature("Uu", 650, 700, "Uu^Uf"),
|
||||
dr_temperature("Uh", 675, 725, "Uh^Uf"),
|
||||
dr_temperature("(Uu,Uh,Uu^Uf)", 850, 999, "Ql"),
|
||||
dr_temperature("Qxu", 800, 999, "Ql"),
|
||||
}
|
||||
res.road_cost = {
|
||||
dr_road("Gll", "Rb", 10),
|
||||
dr_road("Ce", "Rb", 20),
|
||||
dr_road("Gll^Fp", "Rb", 20),
|
||||
dr_road("Gll^Ftr", "Rb", 25),
|
||||
dr_road("Gll^Fet", "Rb", 15),
|
||||
dr_road("Ds", "Rb", 40),
|
||||
dr_road("Ww", "Wwf", 50),
|
||||
dr_road("Gll^Uf", "Rb", 15),
|
||||
dr_road("Hh^Uf", "Rb", 15),
|
||||
dr_road("Hhd^Uf", "Rb", 15),
|
||||
dr_road("Ss", "Rb", 15),
|
||||
dr_road("Aa", "Rb", 10),
|
||||
dr_road("Hh", "Rb", 20),
|
||||
dr_road("Hhd", "Rb", 20),
|
||||
dr_road("Hh^Fp", "Rb", 25),
|
||||
dr_road("Ha", "Rb", 25),
|
||||
dr_road("Ha^Fpa", "Rb", 30),
|
||||
dr_road("Mm", "Rb", 50),
|
||||
dr_road("Ms", "Rb", 55),
|
||||
dr_bridge("Ql", "Ql^Bsb", "Cud", 45),
|
||||
dr_road("Uu", "Rb", 35),
|
||||
dr_road("Uu^Uf", "Rb", 40),
|
||||
dr_road("Uh", "Rb", 45),
|
||||
dr_road("Xu", "Rb", 60),
|
||||
dr_road("Rb", "Rb", 2),
|
||||
dr_road_over_bridges("Ql^Bsb", 2),
|
||||
}
|
||||
res.village = {
|
||||
dr_village {
|
||||
terrain = "Gll",
|
||||
convert_to="Gll^Vh",
|
||||
adjacent_liked="Gll, Ce, Ww, Ww, Ww, Ww, Ww, Wwt, Wwf, Wwf, Rb, Rb, Rb, Rb, Gll, Gll, Hh, Gll^Fp",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gd",
|
||||
convert_to="Gd^Vc",
|
||||
adjacent_liked="Gll, Gll^Fet, Ww, Ww, Ww, Ww, Wwt, Wwf, Wwf, Rb, Rb, Ce, Gd, Gd, Gll, Hh, Hh^Fp, Gll^Fp",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gll^Fp",
|
||||
convert_to="Gll^Ve",
|
||||
adjacent_liked="Gll, Gll^Fet, Ww, Ww, Ww, Ww, Ww, Wwt, Wwf, Wwf, Rb, Rb, Rb, Ce, Gd, Gll, Hh, Hh^Fp, Gll^Fp",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gll^Fet",
|
||||
convert_to="Gll^Ve",
|
||||
adjacent_liked="Gll, Gll^Fet, Ww, Ww, Ww, Ww, Ww, Wwt, Wwf, Wwf, Rb, Rb, Rb, Ce, Gd, Gll, Hh, Hh^Fp, Gll^Fp, Gll^Fp, Gll^Fet, Gll^Fet",
|
||||
rating=7
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ds",
|
||||
convert_to="Ds^Vda",
|
||||
adjacent_liked="Gll, Gll, Wwt, Wwt, Wwt, Wwt, Wwt, Rb, Rb, Rb, Rb, Gll, Gll, Hh, Hh^Fp, Gll^Fp, Gll^Fet, Ds",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uu",
|
||||
convert_to="Uu^Vo",
|
||||
adjacent_liked="Ai,Hh,Mm,Uu,Uh,Uu^Uf,Xu,Rb",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uh",
|
||||
convert_to="Uh^Vud",
|
||||
adjacent_liked="Ai,Hh,Mm,Uu,Uh,Uu^Uf,Xu,Rb",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gll, Gll^Fet, Ww, Ww, Ww, Ww, Ww, Wwt, Wwf, Wwf, Rb, Rb, Rb, Ce, Gd, Gll, Hh, Hh^Fp, Gll^Fp, Gll^Fp, Gll^Fet, Gll^Fet",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hhd",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gll, Gll^Fet, Ww, Ww, Ww, Ww, Ww, Ww, Wwf, Wwf, Rb, Rb, Rb, Ce, Gd, Gll, Hhd, Hh^Fp, Gll^Fp, Gll^Fp, Gll^Fet, Gll^Fet",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Mm",
|
||||
convert_to="Mm^Vhh",
|
||||
adjacent_liked="Gll, Gll^Fet, Mm, Mm^Xm, Ms, Ha, Ha^Fpa, Ww, Wwf, Wwf, Rb, Rb, Ce, Gd, Gd, Gll, Hh, Hh^Fp, Gll^Fp, Gll^Fp, Gll^Fet, Gll^Fet",
|
||||
rating=3
|
||||
},
|
||||
-- villages in snow
|
||||
dr_village {
|
||||
terrain="Aa",
|
||||
convert_to="Aa^Vha",
|
||||
adjacent_liked="Gll, Gll^Fet, Aa, Ai, Ha, Mm, Ms, Ww, Wwf, Wwf, Rb, Rb, Ce, Gd, Gd, Gll, Hh, Hh^Fp, Gll^Fp",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Aa^Fpa",
|
||||
convert_to="Aa^Vea",
|
||||
adjacent_liked="Gll, Gll^Fet, Aa, Ai, Ha, Mm, Ms, Ww, Wwf, Wwf, Rb, Rb, Ce, Gd, Gd, Gll, Hh, Hh^Fp, Gll^Fp",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ha",
|
||||
convert_to="Ha^Vhha",
|
||||
adjacent_liked="Gll, Gll^Fet, Aa, Ai, Ha, Mm, Ms, Ww, Wwf, Wwf, Rb, Rb, Ce, Gd, Gd, Gll, Hh, Hh^Fp, Gll^Fp",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ms",
|
||||
convert_to="Ms^Vhha",
|
||||
adjacent_liked="Gll, Gll^Fet, Aa, Ai, Ha, Mm, Ms, Ww, Wwf, Wwf, Rb, Rb, Ce, Gd, Gd, Gll, Hh, Hh^Fp, Gll^Fp",
|
||||
rating=1
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ss",
|
||||
convert_to="Ss^Vhs",
|
||||
adjacent_liked="Gll, Ss, Ce, Ww, Ww, Ww, Ww, Wwt, Wwf, Wwf, Rb, Rb, Rb, Rb, Gll, Gll, Hh, Gll^Fp",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ww",
|
||||
convert_to="Ww^Vm",
|
||||
adjacent_liked="Ww, Ww",
|
||||
rating=1
|
||||
},
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gll, Gd, Hh, Gll^Ft, Gll^Efm, Gll^Fet, Gll^Ftr, Ss, Ai, Gll^Uf, Hh^Uf, Hh^Fp, Aa, Ha, Ha^Fpa, Mm, Ms",
|
||||
min_distance=13,
|
||||
}
|
||||
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|
183
data/campaigns/World_Conquest/lua/map/generator/provinces.lua
Normal file
|
@ -0,0 +1,183 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
|
||||
local res = wct_generator_settings_arguments( length, villages, castle, iterations, size, players, island)
|
||||
res.max_lakes=5
|
||||
res.min_lake_height=225
|
||||
res.lake_size=90
|
||||
res.river_frequency=80
|
||||
res.temperature_size=size
|
||||
res.roads=90
|
||||
res.road_windiness=6
|
||||
|
||||
res.height = {
|
||||
-- list of common terrain types which come in at different heights, from highest to lowest
|
||||
dr_height(990, "Uh^Uf"),
|
||||
dr_height(980, "Qxu"),
|
||||
dr_height(970, "Uh"),
|
||||
dr_height(950, "Uu^Uf"),
|
||||
dr_height(920, "Uu"),
|
||||
dr_height(915, "Qxu"),
|
||||
dr_height(895, "Uh"),
|
||||
dr_height(885, "Uu^Uf"),
|
||||
dr_height(860, "Uu"),
|
||||
dr_height(840, "Uh"),
|
||||
dr_height(830, "Uu^Uf"),
|
||||
dr_height(800, "Uu"),
|
||||
dr_height(750, "Xu"),
|
||||
dr_height(725, "Mm^Xm"),
|
||||
dr_height(675, "Mm"),
|
||||
dr_height(560, "Hh"),
|
||||
dr_height(100, "Gg"),
|
||||
dr_height(35, "Ds"),
|
||||
dr_height(1, "Ww"),
|
||||
dr_height(0, "Wo"),
|
||||
}
|
||||
res.convert = {
|
||||
-- DR_CONVERT MIN_HT MAX_HT MIN_TMP MAX_TMP FROM TO
|
||||
-- at low temperatures, from medium altitude, snow appears
|
||||
dr_convert(300, 560, 0, 100, "Gg", "Aa"),
|
||||
dr_convert(560, 999, 0, 150, "Hh", "Ha"),
|
||||
-- swamps
|
||||
dr_convert(100, 200, 410, 690, "Gg", "Ss"),
|
||||
dr_convert(370, 400, 410, 430, "Gg", "Ss"),
|
||||
dr_convert(370, 400, 525, 550, "Gg", "Ss"),
|
||||
-- desert appears at extreme temperatures and medium altitude
|
||||
dr_convert(250, 999, 780, 999, "Gg", "Dd"),
|
||||
dr_convert(560, 590, 800, 999, "Hh", "Hd"),
|
||||
-- savannah appears on mod temp and high
|
||||
dr_convert(250, 400, 500, 780, "Gg", "Gs"),
|
||||
-- forest appears at moderate temperatures
|
||||
dr_convert(0, 999, 320, 420, "Gg", "Gs^Fp"),
|
||||
dr_convert(0, 999, 320, 420, "Hh", "Hh^Fp"),
|
||||
-- jungle appears at mod high temperatures
|
||||
dr_convert(0, 999, 450, 520, "Gg,Gs", "Gs^Ft"),
|
||||
dr_convert(0, 999, 450, 520, "Hh", "Hh^Ft"),
|
||||
|
||||
-- lava appears at extreme temperature
|
||||
dr_temperature("Qxu", 850, 999, "Ql"),
|
||||
}
|
||||
res.road_cost = {
|
||||
dr_road("Gg", "Re", 5),
|
||||
dr_road("Gs", "Re", 5),
|
||||
dr_road("Gs^Ft", "Re", 15),
|
||||
dr_road("Gs^Fp", "Re", 15),
|
||||
dr_road("Ss", "Re", 20),
|
||||
dr_road("Ds", "Re", 25),
|
||||
dr_road("Hh", "Re", 15),
|
||||
dr_road("Hh^Fp", "Re", 20),
|
||||
dr_road("Hh^Ft", "Re", 20),
|
||||
dr_road("Mm", "Re", 35),
|
||||
dr_road("Mm^Xm", "Re", 50),
|
||||
dr_bridge("Ql", "Ql^Bs", "Re", 80),
|
||||
dr_bridge("Qxu", "Qxu^Bs", "Re", 80),
|
||||
dr_road("Uu", "Re", 10),
|
||||
dr_road("Uh", "Re", 35),
|
||||
dr_road("Xu", "Re", 50),
|
||||
dr_road("Aa", "Re", 20),
|
||||
dr_road("Ha", "Re", 20),
|
||||
dr_road("Dd", "Re", 15),
|
||||
dr_road("Hd", "Re", 20),
|
||||
dr_road("Re", "Re", 2),
|
||||
dr_road_over_bridges("Ww^Bw", 2),
|
||||
dr_road("Ch", "Ch", 2),
|
||||
dr_bridge("Ww", "Ww^Bw", "Rb", 50),
|
||||
}
|
||||
res.village = {
|
||||
dr_village {
|
||||
terrain = "Gg",
|
||||
convert_to="Gg^Vh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Re, Re, Hh, Gs^Fp",
|
||||
rating=8
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gs",
|
||||
convert_to="Gs^Vht",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Ww, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Re, Re, Hh, Gs^Fp",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ds",
|
||||
convert_to="Dd^Vda",
|
||||
adjacent_liked="Gg, Gs, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Re, Re, Hh, Gs^Fp",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uu",
|
||||
convert_to="Uu^Vud",
|
||||
adjacent_liked="Re,Hh,Mm,Uu,Uh,Xu",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uh",
|
||||
convert_to="Uu^Vu",
|
||||
adjacent_liked="Re,Hh,Mm,Uu,Uh,Xu",
|
||||
rating=3
|
||||
},
|
||||
-- villages in forest are Elvish
|
||||
dr_village {
|
||||
terrain="Gs^Fp",
|
||||
convert_to="Gg^Ve",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Re, Re, Hh, Gs^Fp, Gs^Fp, Gs^Fp",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Re, Re, Hh, Gs^Fp",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Mm",
|
||||
convert_to="Mm^Vhh",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Re, Re, Hh, Gs^Fp",
|
||||
rating=3
|
||||
},
|
||||
-- villages in snow
|
||||
dr_village {
|
||||
terrain="Aa",
|
||||
convert_to="Aa^Vha",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Re, Re, Hh, Gs^Fp",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Aa^Fpa",
|
||||
convert_to="Aa^Vea",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Re, Re, Hh, Gs^Fp",
|
||||
rating=3
|
||||
},
|
||||
-- swamp villages
|
||||
dr_village {
|
||||
terrain="Ss",
|
||||
convert_to="Ss^Vhs",
|
||||
adjacent_liked="Gg, Ww, Ww, Ww, Ww^Bw|, Ww^Bw/, Ww^Bw\\, Re, Re, Re, Re, Hh, Gs^Fp",
|
||||
rating=2
|
||||
},
|
||||
-- mermen villages - give them low chance of appearing
|
||||
dr_village {
|
||||
terrain="Ww",
|
||||
convert_to="Ww^Vm",
|
||||
adjacent_liked="Ww, Ww",
|
||||
rating=1
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uu^Uf",
|
||||
convert_to="Uu^Vud",
|
||||
adjacent_liked="Hh^Uf,Hh,Mm,Uu,Uh,Xu,Qxu,Uu,Uu^Uf,Uu^Uf,Uh^Uf",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uh^Uf",
|
||||
convert_to="Uh^Vud",
|
||||
adjacent_liked="Hh^Uf,Hh,Mm,Uu,Uh,Xu,Qxu,Uu,Uu^Uf,Uh^Uf,Uh^Uf",
|
||||
rating=2
|
||||
},
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gs, Gg, Gs^Fp, Gs^Ft, Hh, Hh^Fp, Hh^Ft, Ss, Mm, Dd, Aa, Ai, Ha",
|
||||
min_distance=14,
|
||||
}
|
||||
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|
65
data/campaigns/World_Conquest/lua/map/generator/savannah.lua
Normal file
|
@ -0,0 +1,65 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
|
||||
local res = wct_generator_settings_arguments( length, villages, castle, iterations, size, players, island)
|
||||
res.max_lakes=10
|
||||
res.min_lake_height=150
|
||||
res.lake_size=125
|
||||
res.river_frequency=100
|
||||
res.temperature_size=8
|
||||
res.roads=12
|
||||
res.road_windiness=10
|
||||
|
||||
res.height = {
|
||||
dr_height(900, "Uh"),
|
||||
dr_height(800, "Uu"),
|
||||
dr_height(750, "Xu"),
|
||||
dr_height(725, "Mm^Xm"),
|
||||
dr_height(675, "Mm"),
|
||||
dr_height(550, "Hh"),
|
||||
dr_height(175, "Gs"),
|
||||
dr_height(30, "Ds"),
|
||||
dr_height(1, "Ww"),
|
||||
dr_height(0, "Wo"),
|
||||
}
|
||||
res.convert = {
|
||||
-- swamp appears on low land, at moderate temperatures
|
||||
dr_convert(nil, 300, 300, 700, "Gg,Gs", "Ss"),
|
||||
-- jungle appears at moderately high temperatures
|
||||
dr_temperature("Gg,Gs", 380, 430, "Gs^Ft"),
|
||||
dr_temperature("Gg,Gs", 460, 520, "Gs^Ft"),
|
||||
-- fungus appears at medium temperatures and extremely high elevation
|
||||
-- DR_CONVERT MIN_HT MAX_HT MIN_TMP MAX_TMP FROM TO
|
||||
dr_convert(825, 950, 500, 525, "Uu, Uh", "Uu^Uf"),
|
||||
dr_convert(825, 950, 550, 575, "Uu, Uh", "Uu^Uf"),
|
||||
dr_convert(825, 950, 600, 625, "Uu, Uh", "Uu^Uf"),
|
||||
-- lava appears at extreme temperatures and elevation
|
||||
dr_convert(800, nil, 900, nil, "Uu, Uh, Uu^Uf", "Ql"),
|
||||
-- desert appears at high temperatures
|
||||
dr_temperature("Gs", 475, 500, "Dd"),
|
||||
dr_temperature("Gs", 600, 650, "Dd"),
|
||||
dr_temperature("Gs", 725, 775, "Dd"),
|
||||
dr_temperature("Gs", 800, 999, "Dd"),
|
||||
-- dunes appear at extreme temperatures
|
||||
dr_temperature("Hh", 625, 650, "Hd"),
|
||||
dr_temperature("Hh", 750, 775, "Hd"),
|
||||
dr_temperature("Hh", 825, 999, "Hd"),
|
||||
}
|
||||
res.road_cost = {
|
||||
wct_generator_road_cost_classic(),
|
||||
dr_road("Ds", "Re", 15),
|
||||
dr_road("Dd", "Re", 15),
|
||||
dr_road("Gs^Ft", "Re", 20),
|
||||
dr_bridge("Ww", "Ww^Bw", "Ce", 50),
|
||||
}
|
||||
res.village = {
|
||||
wct_generator_village(2, 8, 8, 4, 3, 2, 6, 3, 3, 3, 5, 1)
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gs, Gg, Gs^Fp, Hh, Ds, Dd",
|
||||
min_distance=12,
|
||||
}
|
||||
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|
250
data/campaigns/World_Conquest/lua/map/generator/sulfurous.lua
Normal file
|
@ -0,0 +1,250 @@
|
|||
|
||||
local function generate(length, villages, castle, iterations, size, players, island)
|
||||
|
||||
local res = wct_generator_settings_arguments( length, villages, castle, iterations, size, players, island)
|
||||
res.max_lakes=1
|
||||
res.min_lake_height=150
|
||||
res.lake_size=5
|
||||
res.river_frequency=10
|
||||
res.temperature_size=8
|
||||
res.roads=15
|
||||
res.road_windiness=4
|
||||
|
||||
res.height = {
|
||||
dr_height(925, "Uh"),
|
||||
dr_height(820, "Uu"),
|
||||
dr_height(765, "Xu"),
|
||||
dr_height(750, "Mm^Xm"),
|
||||
dr_height(700, "Mm"),
|
||||
dr_height(680, "Hh^Uf"),
|
||||
dr_height(650, "Gs^Fp"),
|
||||
dr_height(625, "Hh^Fp"),
|
||||
dr_height(575, "Hh"),
|
||||
dr_height(400, "Gs"),
|
||||
dr_height(375, "Gs^Fp"),
|
||||
dr_height(325, "Gs"),
|
||||
dr_height(300, "Hh^Fp"),
|
||||
dr_height(275, "Hh"),
|
||||
dr_height(175, "Gs"),
|
||||
dr_height(30, "Ds"),
|
||||
dr_height(1, "Wwt"),
|
||||
dr_height(0, "Wot"),
|
||||
}
|
||||
res.convert = {
|
||||
-- DR_CONVERT MIN_HT MAX_HT MIN_TMP MAX_TMP FROM TO
|
||||
dr_convert(450, 525, 925, 999, "Gs", "Md^Xm"),
|
||||
dr_convert(450, 525, 875, 925, "Gs", "Md"),
|
||||
dr_convert(450, 525, 775, 875, "Gs", "Qlf"),
|
||||
dr_convert(450, 525, 770, 780, "Gs", "Hhd"),
|
||||
dr_convert(450, 525, 525, 770, "Gs", "Dd"),
|
||||
dr_convert(450, 525, 425, 525, "Gs", "Sm"),
|
||||
dr_convert(450, 490, 375, 425, "Gs", "Wwg"),
|
||||
dr_convert(490, 525, 375, 425, "Gs", "Wwrg"),
|
||||
dr_convert(450, 525, 225, 375, "Gs", "Gs^Uf"),
|
||||
dr_convert(450, 525, 10, 225, "Gs", "Gg^Fet"),
|
||||
dr_convert(100, 999, 560, 999, "Gs", "Gd"),
|
||||
dr_convert(100, 999, 10, 385, "Gs", "Gg"),
|
||||
dr_convert(75, 999, 600, 999, "Ds", "Dd"),
|
||||
dr_convert(200, 999, 600, 999, "Hh", "Hhd"),
|
||||
dr_convert(200, 999, 650, 999, "Hh^Uf", "Hhd^Uf"),
|
||||
dr_convert(200, 999, 600, 999, "Mm", "Md"),
|
||||
|
||||
-- DR_TEMPERATURE FROM MIN MAX TO),
|
||||
-- convert forest at different temperatures
|
||||
dr_temperature("Gs^Fp", 900, 999, "Gd^Fdw"),
|
||||
dr_temperature("Hh^Fp", 900, 999, "Hhd^Fdw"),
|
||||
dr_temperature("Gs^Fp", 775, 900, "Gd^Fetd"),
|
||||
dr_temperature("Hh^Fp", 800, 900, "Hhd^Fdf"),
|
||||
dr_temperature("Gs^Fp", 600, 775, "Gd^Fdf"),
|
||||
dr_temperature("Hh^Fp", 700, 800, "Hhd^Fmf"),
|
||||
dr_temperature("Gs^Fp", 560, 600, "Gs^Fet"),
|
||||
dr_temperature("Gs^Fp", 500, 560, "Gs^Ftp"),
|
||||
dr_temperature("Gs^Fp", 450, 500, "Gs^Ftr"),
|
||||
dr_temperature("Hh^Fp", 450, 700, "Hh^Ftp"),
|
||||
dr_temperature("Gs^Fp", 1, 450, "Gg^Ft"),
|
||||
dr_temperature("Hh^Fp", 1, 450, "Hh^Ft"),
|
||||
-- convert cave at different temperatures
|
||||
dr_temperature("Uu,Uh", 850, 999, "Ql"),
|
||||
dr_temperature("Uu", 725, 850, "Uue"),
|
||||
dr_temperature("Uh", 725, 850, "Uue^Dr"),
|
||||
dr_temperature("Uu", 700, 725, "Uue^Uf"),
|
||||
dr_temperature("Uu", 575, 600, "Uu^Uf"),
|
||||
}
|
||||
res.road_cost = {
|
||||
dr_road("Gg", "Re", 10),
|
||||
dr_road("Gg^Ft", "Re", 20),
|
||||
dr_road("Hh", "Re", 30),
|
||||
dr_road("Hhd", "Re", 30),
|
||||
dr_road("Hh^Ftp", "Re", 30),
|
||||
dr_road("Hhd^Fmf", "Re", 30),
|
||||
dr_road("Mm", "Re", 40),
|
||||
dr_road("Md", "Re", 40),
|
||||
dr_road("Mm^Xm", "Re", 75),
|
||||
dr_bridge("Qlf", "Qlf^Bsb", "Cud", 55),
|
||||
dr_bridge("Sm", "Sm^Bw", "Co", 45),
|
||||
dr_road("Uu", "Re", 10),
|
||||
dr_road("Uue", "Re", 10),
|
||||
dr_road("Uh", "Re", 40),
|
||||
dr_road("Xu", "Re", 90),
|
||||
dr_road("Re", "Re", 2),
|
||||
dr_road("Ch", "Ch", 2),
|
||||
dr_road("Dd", "Re", 15),
|
||||
dr_road("Gs", "Re", 9),
|
||||
dr_road("Gd", "Re", 10),
|
||||
dr_road("Gs^Uf", "Re", 12),
|
||||
dr_road("Gs^Ftr", "Re", 20),
|
||||
dr_road("Gs^Ftp", "Re", 20),
|
||||
dr_road("Gs^Fet", "Re", 20),
|
||||
dr_road("Gd^Fdf", "Re", 20),
|
||||
dr_road("Gd^Fetd", "Re", 20),
|
||||
}
|
||||
res.village = {
|
||||
dr_village {
|
||||
terrain = "Gg",
|
||||
convert_to="Gg^Vht",
|
||||
adjacent_liked="Gg, Gs, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Hh, Mm, Hh^Ft, Hh^Ftp",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gs",
|
||||
convert_to="Gs^Vht",
|
||||
adjacent_liked="Gg, Gs, Gd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gs^Uf",
|
||||
convert_to="Gs^Vh",
|
||||
adjacent_liked="Gg, Gs, Gs^Uf, Gs^Uf, Gs^Uf, Gd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd",
|
||||
rating=8
|
||||
},
|
||||
dr_village {
|
||||
terrain = "Gd",
|
||||
convert_to="Gd^Vo",
|
||||
adjacent_liked="Gg, Gs, Gd, Dd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Md, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd, Qlf, Cud, Qlf, Qlf^Bsb|, Qlf^Bsb/, Qlf^Bsb\\",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Ds",
|
||||
convert_to="Ds^Vda",
|
||||
adjacent_liked="Gg, Gs, Wwt, Wwt, Wwt, Re, Re, Hh, Gg^Ft, Gs^Ftp",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Dd",
|
||||
convert_to="Dd^Vd",
|
||||
adjacent_liked="Gg, Gs, Wwt, Wwt, Wwt, Re, Re, Hh, Gg^Ft, Gs^Ftp",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uu",
|
||||
convert_to="Uu^Vud",
|
||||
adjacent_liked=" Re,Hh,Hhd,Mm,Uu,Uh,Xu,Uue,Uue^Dr,Md,Mm^Xm,Md^Xm",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uh",
|
||||
convert_to="Uu^Vud",
|
||||
adjacent_liked=" Re,Hh,Hhd,Mm,Uu,Uh,Xu,Uue,Uue^Dr,Md,Mm^Xm,Md^Xm",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uue",
|
||||
convert_to="Uue^Vo",
|
||||
adjacent_liked=" Re,Hh,Hhd,Mm,Uu,Uh,Xu,Uue,Uue^Dr,Md,Mm^Xm,Md^Xm",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Uue^Dr",
|
||||
convert_to="Uh^Vo",
|
||||
adjacent_liked=" Re,Hh,Hhd,Mm,Uu,Uh,Xu,Uue,Uue^Dr,Md,Mm^Xm,Md^Xm",
|
||||
rating=5
|
||||
},
|
||||
-- villages in forest are Orcish
|
||||
dr_village {
|
||||
terrain="Gs^Ftp",
|
||||
convert_to="Gs^Vo",
|
||||
adjacent_liked="Gg, Gs, Gd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gg^Ft",
|
||||
convert_to="Gg^Vo",
|
||||
adjacent_liked="Gg, Gs, Gd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gs^Ftr",
|
||||
convert_to="Gs^Vo",
|
||||
adjacent_liked="Gg, Gs, Gd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gd^Fdf",
|
||||
convert_to="Gd^Vo",
|
||||
adjacent_liked="Gg, Gs, Gd, Dd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Md, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd, Qlf, Cud, Qlf, Qlf^Bsb|, Qlf^Bsb/, Qlf^Bsb\\",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Gd^Fetd",
|
||||
convert_to="Gd^Vo",
|
||||
adjacent_liked="Gg, Gs, Gd, Dd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Md, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd, Qlf, Cud, Qlf, Qlf^Bsb|, Qlf^Bsb/, Qlf^Bsb\\",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh",
|
||||
convert_to="Hh^Vhh",
|
||||
adjacent_liked="Gg, Gs, Gd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd",
|
||||
rating=4
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh^Ftp",
|
||||
convert_to="Hh^Vo",
|
||||
adjacent_liked="Gg, Gs, Gd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hh^Ft",
|
||||
convert_to="Hh^Vo",
|
||||
adjacent_liked="Gg, Gs, Gd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hhd^Fmf",
|
||||
convert_to="Hhd^Vo",
|
||||
adjacent_liked="Gg, Gs, Gd, Dd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Md, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd, Qlf, Cud, Qlf, Qlf^Bsb|, Qlf^Bsb/, Qlf^Bsb\\",
|
||||
rating=2
|
||||
},
|
||||
dr_village {
|
||||
terrain="Hhd",
|
||||
convert_to="Hhd^Vd",
|
||||
adjacent_liked="Gg, Gs, Gd, Dd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Md, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd, Qlf, Cud, Qlf, Qlf^Bsb|, Qlf^Bsb/, Qlf^Bsb\\",
|
||||
rating=5
|
||||
},
|
||||
dr_village {
|
||||
terrain="Mm",
|
||||
convert_to="Mm^Vhh",
|
||||
adjacent_liked="Gg, Gs, Gd, Dd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Md, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd, Qlf, Cud, Qlf, Qlf^Bsb|, Qlf^Bsb/, Qlf^Bsb\\",
|
||||
rating=3
|
||||
},
|
||||
dr_village {
|
||||
terrain="Md",
|
||||
convert_to="Md^Vd",
|
||||
adjacent_liked="Gg, Gs, Gd, Dd, Re, Re, Gs^Ftr, Gs^Ftp, Gs^Fet, Gg^Ft, Gd^Fdf, Gd^Fetd, Hh, Mm, Md, Hh^Ft, Hh^Ftp, Hhd^Fmf, Hhd, Qlf, Cud, Qlf, Qlf^Bsb|, Qlf^Bsb/, Qlf^Bsb\\",
|
||||
rating=4
|
||||
},
|
||||
-- mermen villages - give them low chance of appearing
|
||||
dr_village {
|
||||
terrain="Wwt",
|
||||
convert_to="Wwt^Vm",
|
||||
adjacent_liked="Wwt, Wwt, Wot, Ds",
|
||||
rating=1
|
||||
},
|
||||
}
|
||||
res.castle = {
|
||||
valid_terrain="Gs, Gg, Gd, Gs^Fp, Gg^Ft, Gs^Ftr, Gs^Fet, Gd^Fetd, Gd^Fdf, Hh, Hhd, Dd, Mm, Md, Sm, Hh^Fp, Hh^Ftp, Hh^Fmf, Hh^Ft",
|
||||
min_distance=13,
|
||||
}
|
||||
|
||||
return default_generate_map(res)
|
||||
end
|
||||
return generate
|