Fulqrum Publishing Home   |   Register   |   Today Posts   |   Members   |   UserCP   |   Calendar   |   Search   |   FAQ

Go Back   Official Fulqrum Publishing forum > Fulqrum Publishing > King's Bounty > King's Bounty: The Legend > Mods

Mods Everything about mods

Reply
 
Thread Tools Display Modes
  #1  
Old 03-17-2013, 11:40 PM
MattCaspermeyer MattCaspermeyer is offline
Approved Member
 
Join Date: Aug 2010
Posts: 553
Default Mod Tutorials - Unit Features / Spell Functions

I received a private message from @BB_Shockwave, but unfortunately my response exceeded the 5000 character limit so I thought I'd put the response here in how it applies to TL and then as it applies to AP / CW / WotN.

Quote:
Originally Posted by BB Shockwave
Hi!

You seem like the most versed person in modding -just a quick question, as I was unable to find the file in ses.kfs where unit abilities are described, can you tell me which file has them? Not talents, but stuff like "Magic resistance", "Nimble", etc...

The other thing I could not find yet are the logic files for spells. Spells.txt only lists basic mechanics. Namely, I want to try and fix the Ice Snakes spell so it indeed heals Ice Creation units.
Hi!

I think you're probably specifically referring to WotN if I'm not mistaken...

It should not matter, though, if you're talking about the items below the unit's abilities - i.e. their features (I'll be referring to stuff in TL, but it should be very similar for WotN).
  1. The features only appear if they are listed in the unit's ATOM on the features_hints line. This is usually the second line below the unit's arena_params section (if you are your text editor's find function, otherwise just search for it within your editor). Also note that the order is header / hint when you specify a new feature ("/" separates the header and hint and a "," separates different features). Also note that these are just text headers / hints, they don't give a unit that feature unless you specify it on their features line (also in arena_params but usually just before their resistances section (also in arena_params)). You have to be careful here, though, because just because you have a unit feature, it does not mean it is a real feature. The real features are listed in LOGIC.TXT on the features line. Real features are things like Mind Immunity, Fire Immunity, etc. Fake features are things like Poison Resistance, Acid Spray, etc. that are special to the unit, but not used to delineate the unit or exclude it from certain things like a real feature can. For example, you'll see that mage is on the features list of LOGIC.TXT and so this is how Zerock's damage abilities were able to do double damage to Mages - because they had mage specified on their features line in their ATOM's. So only add a feature to the ATOM's feature line if you want it to be used as a check for including / excluding units that have that feature (also ensure that it is in LOGIC.TXT - you can add new features there as well).
  2. All unit features are listed in EN(G)_UNIT_FEATURES.LNG (or your specific localization language prefix). This file is (and all *.LNG files are) located in your LOC_SES.KFS file and has two parts:
    1. CPI_*_FEAT - this is the feature text names that go with the header / hint you specify on the unit's features_hints line in their ATOM file and note that "*" refers to the name of the unit and it must match the name of their ATOM file (i.e. Pirate must be CPI_PIRAT_FEAT because their ATOM is PIRAT.ATOM, etc.). Note that these are the exact names that you'll see in the unit's feature list so they should be descriptive and user friendly. Also note that since you specify headers / hints in the ATOM and then their text name here that you have to be careful to ensure that your names line up. In my alpha H3T mod you'll see where I fixed the bug in CW with the Ice Ball (level 3) headers / hints and the text listing because they were not ordered properly / missing. So if you list Poison Resistance and Fire Resistance on the CPI_*_FEAT line, but specify them as fire_resistance_header/fire_resistance_hint, poision_resistance_header/poison_resistance_hint in the ATOM's features_hints line for that unit, it will pull up Fire Resistance when you point to Poison Resistance in the unit's feature list and vice versa. There is no check for this so I just want you to be aware of this otherwise it will cause you grief if you're not careful.
    2. *_HEADER & *_HINT - the name of your headers / hints where "*" refers to the name, i.e. you'll see for Peasants that Team Spirit is called comradeship and that it has a comradeship_header which is the name of the feature and a comradeship_hint that is the text description of that feature. Basically when you point to the unit's feature in their feature list, you'll get a text box with the header being the name you see as the title of the text box (this should match the name in the feature list, but it doesn't have to) and the hint will be what is specified below in the main part of the text box. Also you'll see ^def_hint_t0^ for headers and ^def_hint_t1^ for hints right after the "=" before the text. These are the macro templates (The carets, ^, delineate the template name) that are defined in TEMPLATES.LNG. A macro is simply a keyword that needs to be defined in the template that executes either an LUA function or replaces the keyword with a text label. As it turns out in TL, there were a lot of limitations to the LUA's accessibility to certain unit parameters when pointing to features, which I'm hoping were addressed in AP / CW / WotN. For example, I thought it would be nice to specify the percent damage from arrows to Bone creatures and have it specified via a parameter in their ATOM, but I had trouble doing it in TL (it is simply listed as a static value, so if you were modding and wanted to change it to a different value you'd have to update EN(G)_UNIT_FEATURES.LNG as well as other places where it is used). Maybe I just didn't know how to do it back then, but you'll have to experiment with the macro capability in WotN for unit features if you want it to display dynamic (as opposed to static) unit data in your hints (see EN(G)_UNITS_SPECIALS.LNG and you'll see that they used quite a few macros in the text descriptions for listing probabilities, etc. of unit special abilities, i.e. talents).
Okay, well that's the technical description, let's look at an example so that it becomes more obvious. Using my H3B TL files (they should be very similar in the stock files), let's look at the Alchemist.

ALCHEMIST.ATOM (located in DATA.KFS):

Code:
arena_params {
  features_label=cpi_alchemist_feat
  features_hints=poison_resistance_header/poison_resistance_hint,acid_sprays_header/acid_sprays_hint,no_melee_header/no_melee_hint,dungeon_liker_header/dungeon_liker_hint,sea_sick_header/sea_sick_hint  race=dwarf
.
.
.
  features=shot,humanoid
  resistances {
    physical=8
    poison=33
    magic=8
    fire=8
  }
.
.
.
}
So note the features listed on the features_hints line and also the features line: shot and humanoid are used to determine certain AI functions and also give certain bonuses to units with that feature listed, whereas Poison Resistance, Acid Spray, Likes Dungeons, and Sea Sick are not used as criteria for including / excluding this unit based on these features and are not included on the features line in LOGIC.TXT (located in SES.KFS, see below) nor in ALCHEMIST.ATOM (see above).

LOGIC.TXT:

Code:
.
.
.
races=human,elf,orc,dwarf,undead,demon,neutral
resistances=physical,poison,magic,fire,astral
features=armor,shot,mage,undead,eyeless,demon,dragon,plant,mind_immunitet,fire_immunitet,magic_immunitet,poison_immunitet,freeze_immunitet,holy,bone,golem,humanoid,beast,beauty,nonecro,barrier,archer,boss,pawn,orb,wood,cute
.
.
.
EN(G)_UNITS_FEATURES.LNG (located in LOC_SES.KFS):

Code:
cpi_alchemist_feat=Poison Resistance, Acid Spray, No Melee Penalty, Likes Dungeons, Sea Sick.
Note the order of those listed and compare it with the features_hints line in ALCHEMIST.ATOM (see above).

Looking further in EN(G)_UNITS_FEATURES.LNG:

Code:
.
.
.
no_melee_header=^def_hint_t0^No Melee Penalty
no_melee_hint=^def_hint_t1^The creature inflicts the same damage during Melee and Ranged Attacks.
.
.
.
acid_sprays_header=^def_hint_t0^Acid Spray
acid_sprays_hint=^def_hint_t1^It discharges an Acid Spray within the area of 3 cells, which burns all in its reach. An enemy has no ability to retaliate. The alchemist receives some of the bonuses which apply to archers.
.
.
.
poison_resistance_header=^def_hint_t0^Poison Resistance
poison_resistance_hint=^def_hint_t1^Gives the creature +25% Resistance to Poison Damage.
.
.
.
dungeon_liker_header=^def_hint_t0^Likes Dungeons
dungeon_liker_hint=^def_hint_t1^Likes dungeons: +25% Attack in dungeons.
.
.
.
sea_sick_header=^def_hint_t0^Sea Sick
sea_sick_hint=^def_hint_t1^Gets sick at sea: -2 Morale.
So here you just see how the header and hints are setup and defined (by the way, where you see +25% and -2 it'd be nice to replace those with a template macro and have then defined elsewhere).

TEMPLATES.LNG (located in LOC_SES.KFS):

Code:
def_hint_t1=<shadow=off><font=ft1_14><color=255,243,179><align=left>$
def_hint_t1 {
  moral=<gen=unit_moral_text>
  mdesc=<gen=unit_moral_desc>
  br=<br>
  sys=<color=222,194,94>
  sel=<color=250,250,240>
  dis=<color=138,138,132>
  /c=</color>
  res=<br><color=222,194,94><label=cpi_defense_res></color><gen=gen_unit_res>
  hero_lead=<color=250,250,240><gen=gen_lead_count,hero></color>
  lead=<color=250,250,240><gen=gen_lead_count,unit></color>
  unit_count=<color=250,250,240><gen=gen_lead_count></color>
  add=<gen=gen_lead_count,add>
  unit_max_count=<color=250,250,240><gen=gen_lead_count,max></color>
  allhp=<gen=gen_max_hp>
  krit=<br><color=222,194,94><label=cpi_attack_krit></color><gen=gen_unit_krit>
}
.
.
.
def_hint_t0=<shadow=off><align=center><font=ft1_14><color=255,243,179>$
.
.
.
So here you can see that def_hint_t0 doesn't have any macros but does have some display information. On the other hand, def_hint_t1 does have quite a few (gen= is a call to an LUA function) so if you wanted to add a new macro you can add it here. Note that I added a new macro, krit, to this one so you can see how I did the Critical Attack in my mod.

Now for the variants to these for AP / CW / WotN. When it came to the text information files (ATOM, TXT, LNG) these were modified with the names staying the same. For the LUA functions, they used the same names for when they modified the stock TL functions. For example, spells that were in SPELLS.LUA were modified per the new AP (i.e. spells like Dispel, Bless, Divine Armor, etc.) in SPELLS.LUA. New spells were put in ADDON_SPELLS.LUA. For AP, both of these files were in SES.KFS. As it turns out, new spells were just appended to the end of SPELLS.TXT rather than creating an ADDON_SPELLS.TXT (which they could have easily done). ATOM's were still in DATA.KFS and all *.TXT in SES.KFS, and *.LNG in LOC_SES.KFS. When they went to CW, they decided to "mod" AP and add all the files to ORCS.KFS (i.e. ATOM's, TXT's, LNG's, etc.). They also created some new LNG files like EN(G)_CHAOS_DRAGON.LNG which not only has Chaos Dragon stuff, but also Shaman and Bone Dragon stuff (go figure). They also created a SPELLS_SPIRIT.TXT file to include the new Spirit Spells (note that there is an ==spells_spirit.txt line at the beginning of the CW SPELLS.TXT file to include other text files). So it is best to get a text editor with a GREP function that allows you to search for text strings in all files (this is what I have and what I needed to find stuff back in the day and now as I modded and am continuing to mod). For WotN they did similar as with CW, but instead of a single *.KFS file they put new ATOM's in SES.KFS, but added new *.LNG's to LOC_SES.KFS.

Okay, now on to your second request.

I'm not sure if you've realized this, but the way the game is laid out, there are a series of text files that describe objects like units, spells, features, etc. and then there are the LUA scripts that perform some sort of implementation of these kinds of things.

So it sounds like you found where Ice Snake is in SPELLS.TXT, but then there are a series of lines in the "scripted" section of that spell's information that describe the LUA functions that it uses. Looking at SPELLS.TXT for WotN:

Code:
.
.
.
spell_ice_serpent {
  category=s
  profit=4
  price=16000
  image=book_spell_ice_serpent.png
  button_image=book_scroll_ice_serpent.png
  label=SN_ice_serpent
  attack=scripted
  school=4
  hint_config=object_spell
  hint=spell_ice_serpent_hint
  hint_header=spell_ice_serpent_header
  
  scripted {
    script_attack=spell_ice_serpent_attack
    script_highlight=spell_ice_serpent_highlight
    script_calccells=calccells_ice_serpent
    attack_cursor=magicstick
    ad_factor=0  // use attack/defense
    nfeatures=magic_immunitet
  }
  params {
    duration=0
    typedmg=glacial
    peri_typedmg=physical
    damage=130		// óðîí öåëè
    peri_damage=20-60	// óðîí ñîñåäÿì
    lvl_dmg=110
    freeze=20    //âåðîÿòíîñòü çàìîðîçêè * íà óðîâåíü
    bleed=10     //âåðîÿòíîñòü êðîâîòå÷åíèÿ * íà óðîâåíü
    bonus=70     //ëå÷åíèå ëåäÿíûõ ñîçäàíèé
  }
  levels {
    // level = mana_cost, crystals_cost to upgrade from previous level
    1=10,8
    2=20,14
    3=30,20
  }
}
.
.
.
You'll see that the script attack is set to spell_ice_serpent_attack. This is the LUA function for determining the behavior of the spell and this is the part that you'd want to modify. If you use your GREP, you'll see that this is located in SPELLS.LUA (this is where it is located for all KB variants by the way since it is an original spell). What is interesting is that if I look at this file (I think it is the original WotN release) they have a check where they are checking to see if a creature is ice_creature and if it is they heal it:

Code:
.
.
.
    if Attack.act_feature(target, "ice_creature") then
      Attack.log_label("null")
      local delta_hp = Attack.act_get_par(target, "health") - Attack.act_hp(target)
      if heal > delta_hp then
        heal = delta_hp
      end
      Attack.act_cure(target, heal, dmgts)
      if Attack.act_size(target) > 1 then
        Attack.log("add_blog_sheal_2", "hero_name", blog_side_unit(target, 4)..Attack.hero_name(), "spell", blog_side_unit(target, 3).."<label=spell_ice_serpent_name>", "special", cure_hp, "target", blog_side_unit(target, -1))
      else
        Attack.log("add_blog_sheal_1", "hero_name", blog_side_unit(target, 4)..Attack.hero_name(), "spell", blog_side_unit(target, 3).."<label=spell_ice_serpent_name>", "special", cure_hp, "target", blog_side_unit(target, -1))
      end
    else
.
.
.
If I look in WotN's LOGIC.TXT:

Code:
.
.
.
races=human,elf,orc,dwarf,undead,demon,neutral,lizard,viking
resistances=physical,poison,magic,fire,glacial,astral
features=armor,shot,mage,undead,eyeless,demon,dragon,plant,mind_immunitet,fire_immunitet,magic_immunitet,poison_immunitet,freeze_immunitet,scare_immunitet,holy,bone,golem,humanoid,beast,nonecro,barrier,archer,boss,pawn,orb,mech,summoned_creature,rune_knowledge,ice_creature,light_step,ghost
.
.
.
I see ice_creature third from last in the list and so next would be to check what are Ice Creatures: DRAGON_ICE, ICE_BLADES, ICE_BLADES_WALL, ICE_MINION, ORB1, ORB2, and ORB3 (all of these are ATOM's).

So I'm not sure why it wouldn't be working unless it is changed in the patches or the unit is not on the above list.

Okay, so there you have it! If you have any comments or questions, don't hesitate to ask!

/C\/C\
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 09:07 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright © 2007 Fulqrum Publishing. All rights reserved.