Jump to content

Notes on various txt files


Recommended Posts

"et_range_near" - used by "cSpellInqVergeltung" spellclass - defines Area of Effect radius for spell-damage entry.

 

"cSpellInqVergeltung" spellclass is very useful. It accepts "et_shieldstrength", "et_shieldblock", "et_shieldfactor", "et_shield_regen" entries and can be used to make force-field type spells. It wont' recognize "et_range_area" and, as such, can't be used for minion-strengthening buffs.

 

all attribute adding entries, like "et_addattr_willpower" dont' work well with most minion-friendly spellclasses(periodic changes in expected bonus amount 0 to x2, weapon special effects flicking :twitch: ). Only "cSpellDmVertrauter" spellclass works reliably, but adds a nice rotating fireball anim.

 

Belligerent Vault is somewhat hardcoded and is allergic to attempts to turn it into a weapon-based art. It won't recognize "et_mult_weapondamage". Even substituting every​ string with strings from Assaulting Sommersault doesn't work. Spell Damage only.

 

Llama8 has made a very useful excel file a while back. Using it as a cross-reference we can safely assume that:

 

"et_shield_none" and "et_minion_boost" are property-free tokens and can be used to add unused properties to spells.txt

Edited by dimitrius154
Link to comment

Here's a few more unused or non-functioning spell tokens. I re-purposed all of these for the Diablo mod and replaced their values. A modder has to do this since the game won't accept new tokens added to the bottom of the list.

 

"et_chance_dismount"

"et_RangeOfSight"

"et_range_aggro"

"et_dotdamping_any"

"et_debuff_strangle"

"et_provo_area"

"et_provo_target"

 

For example, this is the new definition:

mgr.addTokenBonus( {"et_provo_target", 906 }) -- 906 = bb_chance_block_CC

 

I replaced the original number with "906" which is Block Chance: Close Combat value in blueprint.txt. Now "et_provo_target" adds that block chance when added to a buff.

  • Thanks! 1
Link to comment

"et_RangeOfSight"​ is working - it's the visibility bonus, that allows to see enemy markers further away on the minimap

"et_dotdamping_any" - isn't it the debuff to detrimental effects property?

Edited by dimitrius154
Link to comment

"et_RangeOfSight"​ is working - it's the visibility bonus, that allows to see enemy markers further away on the minimap

"et_dotdamping_any" - isn't it the debuff to detrimental effects property?

 

Oh they work, they're just unused in spells.txt. No spells call on them.

  • Like! 1
Link to comment
  • 2 weeks later...

"game_directory"\scripts\server\creatures.txt, "game_directory"\scripts\shared\spells.txt:

--------

 

Summoned hireling AI seems unaffected by "behaviour" string and appears to be substituted by parameters from "spellClass" string from spells.txt.

 

The "cSpellSkKohorte" (Nether Allegiance) spellclass does not allow summons to cast spells.

 

The "cSpellInqDoppelgaenger" (Zealous Doppelganger) spellclass allows to utilize both spells and weapons, but allows only one summon and "applies blue transparent noise" shader on it.

 

The "cSpellHeFeuerdaemon" (Fire Demon) spellclass allows to summon multiple spellcasters(which will cast at least two available spells), but ignores equipment altering entries.

Edited by dimitrius154
Link to comment

Yeah it really sucks trying to make a melee summon that uses weapon-based combat arts. The caster AI makes them just wander around a lot when they should be attacking.

Link to comment

Actually, the "sk_ap_kohorte" (Nether Allegiance) spell with "cSpellHeFeuerdaemon" spellclass skeleton mage minions attack pretty reliably, the action rate is the same as with original melee minions.

 

The "cSpellInqDoppelgaenger" spellclass, however, does impose awkward delays in AI actions(must be switching between melee and ranged too often).

Link to comment

"game_directory"\scripts\server\blueprint.txt

--------

I've encountered a "splendid" "feature" upon saving this particular file in notepad(?!), or MS Word, under Windows 10. It becomes corrupted - the equipment parameter, slot and boni entries are no longer recognized by the game. The only reliable stock editor has been Wordpad.

Link to comment

That hasn't been my experience. Are you talking about a custom spell you made or the one from Diablo 2 Fallen?

 

A custom spell - stock Nether Allegiance + Fire Demon spellclass + custom armored lich model, based on legion skeleton mage.

 

Just for the benefit of anyone reading this thread, no one should be using Notepad or MS Word to edit the game scripts.

 

Thing is, only blueprint.txt is affected, from my experience. Global.res, by the way, the English version, at least, is not corrupted by Notepad.

Edited by dimitrius154
  • Like! 1
Link to comment

Global.res, by the way, the English version, at least, is not corrupted by Notepad.

You're probably right. Usually what happens is I will send snippets for translation (in UCS-2 LE) and I will get the translations back in ANSI because the translator used Notepad. I just automatically blamed the text editing program.

Link to comment

"game_directory"\scripts\server\creatures.txt, "game_directory"\scripts\shared\spells.txt:

--------

 

By utilizing "cSpellHeFeuerdaemon" class, the "Hireling_brave" behavior, proper spell assignment sequence and proportionate spell cooldowns, minions may cast up to 3 offensive spells + 1 buff.

 

the spell assignment should be like:

spells = {
entry0 = { "kohorte_eifer" }, -- buff, must be first string
entry1 = { "kohorte_feuersturm" }, -- first spell choice, cooldown > second spell choice cooldown
entry2 = { "kohorte_energiebrand" }, -- second spell choice
entry3 = { "kohorte_giftschlag" }, -- third spell choice, cooldown == 0, spellcontroltype = "eCAtype_a_weapon_attack"
},

  • Like! 1
Link to comment

Great, the minions react poorly to being assigned permanent buffs, or buffs with duration set by "et_duration_sec" entry:

 

Permanent buffs: once you teleport to another location, some buff connected flag gets reset, the visuals disappear, and minions start recasting the buff - ad infinitum.

"et_duration_sec": duration is ignored and set to 0 - minions start recasting the buff.

:blowup:

 

What works is using duration string and "et_duration_boost" entry to define duration + spellclass, that accepts that entry. Example:

 

mgr.defineSpell( "kohorte_eifer", {
eiStateName = "cSpellCast",
fxTypeCast = "FX_SK_KAMPFRUF_C",
fxTypeSpell = "FX_SK_KAMPFRUF",
fxTypeCastSpecial = "FX_SK_KAMPFRUF_C",
duration = 750.000000,
animType = "ANIM_TYPE_MAGICB",
animTypeApproach = "ANIM_TYPE_INVALID",
animTypeRide = "ANIM_TYPE_INVALID",
animTypeSpecial = "ANIM_TYPE_INVALID",
causesSpellDamage = 1,
tokens = {
entry0 = {"et_duration_boost", 1000, 10, 0, 8 },
entry1 = {"et_life_leech_rel", 20, 0, 0, 41 },
entry2 = {"et_energy_leech_whit", 95, 0, 0, 5 },
entry3 = {"et_damage_areasplash", 745, 5, 0, 9 },
entry4 = {"et_addCastspeed", 198, 2, 0, 37 },
entry5 = {"et_addWeaponSpeed", 198, 2, 0, 37 },
entry6 = {"et_chance_evade", 198, 2, 0, 41 },
entry7 = {"et_addwalkspeed", 198, 2, 0, 41 },
},
fightDistance = 0.000000,
aspect = "EA_ENEMY_ANY",
cooldown = 15.000000,
soundProfile = 0,
cost_level = 10,
cost_base = 10,
focus_skill_name = "skill__enemy_focus",
lore_skill_name = "skill__enemy_lore",
spellClass = "cSpellAttackScream",
spellcontroltype = "eCAtype_b_boost_self",
sorting_rank = 0,
})

Edited by dimitrius154
Link to comment

"game_directory"\scripts\client\animation.txt:

--------

 

This file defines animations for heroes, mounts, monsters etc., and their parameters: lengths and timings for breakpoint events, like attacks and jumps. Important for some CA changes.

For example, if you want to change the Belligerent Vault CA damage from spell to weapon based, not only do you need to change eistate to "cSMRoundhouse", spellclass to "cSpellSMove" and spellcontroltype to "eCAtype_m_attackmove_jump", but you need to add an attack event (["ATTACK"] = 1.6000,) to all ["itemType"] = 3 (that's shadow warrior) SM09 entries (499 to 508) in animation.txt. ( Yes, my statement in a previous post about spell damage only for Belligerent Vault is no longer valid :) )

Edited by dimitrius154
Link to comment

"game_directory"\scripts\behaviour.txt:

--------

This file defines various AI for npc's, but what's important is that summoning spellclasses use entries with hardcoded name pointers from this file for summon's behavior, not hardcoded parameters of their own. That gives room for manipulation of summon AI :)

 

"cSpellSkKohorte" uses "Hireling_brave"

"cSpellHeFeuerDaemon" uses "Hireling_distance"

 

You can reliably guess what AI is being used by referencing unmodded creatures.txt's behavior string for the creature, but keep in mind, that spellclasses substitute AI's from creatures.txt, not use them.

 

For example, we want to turn our spectral soldiers(Nether Allegiance) into liches, cuz no Necromancer is respected, if he has no undead mages in his retinue. Custom model in place, skills ready, spells ready, equipment ready and... your mages run into the thick of it, bashing with their staves, not a single spell cast. Why? Because "Hireling_brave" entries define behavior as simple movement and weapon attacks:

newBehaviour = {
name         = "Hireling_brave",
state0       = "name=cCreatureIdleAI",
state1       = "name=cHirelingMoveAI,range=200.0,attitude=brave,fightstate=cEnemySimple",
state2       = "name=cEnemySimple,distance=300.0,feasibility=0,waitingtime=0.5,health_threshold=0,flee_probability=0",
setState0    = "condition=onGroupMemberAttack,feasibility=1000,state=cEnemySimple",
defaultState = "cHirelingMoveAI",
}

So what we do is replace entries with those from "Hireling_mage_no_defense", like so:

newBehaviour = {
name         = "Hireling_brave",
state0       = "name=cCreatureIdleAI",
state1       = "name=cHirelingMoveAI,range=200.0,attitude=brave,fightstate=cEnemyMagician",
state2       = "name=cEnemyMagician,defense=cEnemySimpleDefence,doDefense=0,forceidle=1",
state3       = "name=cEnemySimpleDefence,numattack=3,distance=400",
state4       = "name=cSpecialMoveAI",
setState0    = "condition=onGroupMemberAttack,feasibility=1000,state=cEnemyMagician",
defaultState = "cHirelingMoveAI",
}
mgr.createBehaviour(newBehaviour);

 

And voila, the behavior is as expected - spells fly (with proper cooldown timings - for different offensive spells at least). Don't assign permanent buffs, however. There's an annoying bug - when player teleports to another location, some flag gets reset, and AI thinks the buff is gone, tries to recast it, fails, tries again... and is stuck :cry: ( I wonder, if that's the case with stock creature - the Fire Daemon).

Edited by dimitrius154
  • Like! 1
Link to comment

That's a nice solution, but then every creature that uses "hireling_brave" will act like a spellcaster. If you wanted a different minion to have no spells and run in and attack like the original behavior, would it still do so with "cSpellSkKohorte" spellclass?

Link to comment

Ahh yes, without spells they don't attack. Another surprise from Ascaron devs. You know, way back, in Sacred Underworld sacred.exe they actually coded the effects for the Christmas Set twice​ - first instance for the Wood Elf, and second for the rest of the chars.

 

All right, bypass: use spellclass "cSpellHeFeuerdaemon" and behavior "Hireling_distance" (only Fire Daemon uses it, and won't be badly affected, since it's a caster, technically)

newBehaviour = {
name         = "Hireling_distance",
state0       = "name=cCreatureIdleAI",
state1       = "name=cHirelingMoveAI,range=200.0,attitude=brave,fightstate=cEnemyMagician",
state2       = "name=cEnemyMagician,defense=cEnemySimpleDefence,doDefense=1,forceidle=0",
state3       = "name=cEnemySimpleDefence,numattack=3,distance=400",
state4       = "name=cSpecialMoveAI",
setState0    = "condition=onGroupMemberAttack,feasibility=1000,state=cEnemyMagician",
defaultState = "cHirelingMoveAI",
}
mgr.createBehaviour(newBehaviour);
Edited by dimitrius154
  • Like! 1
Link to comment

By the way, the "Hireling_brave_ex" behaviour allows to use weapons and cast offensive spells, but not defensive ones. The Dragon Mage Protector CA minion can be a spellcaster, since the "cSpellDmBeschuetzer" uses "Hireling_brave_ex" :)

Link to comment

The Protector seemed to need a fix to get him to cast his spells. In Llama's Mod he changed the spellclass to "cSpellHeFeuerdaemon" and I imported this change into my Enhanced Spells mod. One of the Protector's spells was "enemy_heal_self" which is defensive so that may be why he never cast it in the un-modded game.

 

I should experiment with behavior.txt some more and see if I can't evoke some satisfying AI for the various minions of D2F.

Link to comment

"game_directory"\scripts\server\equipsets.txt:

--------

In this file various equipment sets for both heroes and npcs are defined in a rather unfortunate manner, since the meaning of the first number in set = {} entries is not clear. However, if you Alt+Tab during an active game session, you'll find the "game_directory"\scripts\server\weaponpool.txt file, which contains entries for items in currently loaded areas of the game. Those entries contain the "dbid = " string. I'm positive, that those dbid parameters are those very numbers from equipsets.txt entries :) .

 

Therefore, to decipher the equipment sets contents it would be best to use some area as testing ground, and place every npc type there, enter the area, Alt+Tab, then open weaponpool.txt and write down all dbid's with reference to what item each dbid represents. That would allow to create a useful reference table for modders.

 

By the way, the fact, that the game creates and overwrites multiple files in scripts folder during, is a valid explanation for all troubles folks are having, if they install the game into one of the protected or restricted folders.

Edited by dimitrius154
Link to comment

It's easy to trace equipsets all the way back to the models and textures in use.

 

Creatures.txt --> Equipsets.txt --> Weaponpool.txt --> Blueprint.txt --> Itemtype.txt --> Surface.txt

 

Each entry within each script references an entry in the script to its right.

 

Random example:

 

mgr.createCreature {
	id = 906,
	itemtype_id = 7965,
	name = "Orc_warrior_armoured_blue",
	behaviour = "Enemy_warrior_simple",
	dangerclass = 5,
	groupmaxcount = 3,
	elite_creature_id = 906,
	probabilityforelite = 0.000000,
	rank = 10,
	tenergy_creature_id = 251,
	template_creature_id = 1341,
	livesremaining = 0,
	unconscioustime = 20,
	palettebits = "1111111111111111",
	monstertype = 0,
	speakertype_id = 2,
	faction_id = 34,
	equipset_id = 244, –– Here's our equipset ID
	modelscale = 1.000000,
	rise_from_ground = 0,
	has_corpse = 1,
	has_soul = 1,
	can_strafe = 0,
}

 

244 in equipset.txt gives us:

 

-- NPC_orc_armoured
mgr.createEquipset {
	id = 244,
	set = {
		{ 636, EQUIPSLOT.AUTO, 1}, -- 636 is the weaponpool entry
	}
} 

 

Now we look up 636 in Weaponpool.txt:

 

mgr.addWeaponPool { -- NPC_orc_2h_axe
	dbid = 636,
	prefDmg = 1,
	prefDmgProb = 0,
	content = {923,}, -- 923 is the blueprint entry
	contentProb = {1,},
}

 

Now we look up 923 in blueprint.txt:

 

newBlueprint = {
  id = 923,
  name = "NPC_orc_2h_axe",
  palettebits = "1111111111111111",
  dmgvariation = 170,
  minconstraints = {1,1,0},
  lvljump = 1,
  usability = 0,
  allotment_pmfpi = {1000,0,0,0,0},
  uniquename = "",
  specialuseonly = 0,
  itemtypes = {7742,}, -- here is the itemtype number
  wearergroups = {'WEARGROUP_NPC_ONLY',},
}
mgr.createBlueprint(923, newBlueprint); 

 

7742 in itemtype.txt gives us:

 

newItemType = {
	-- standard info
	renderfamily = "RENDERFAM_WEAPON",
	renderprio   = 0,
	family       = "FAMILY_WEAPON",
	subfamily    = "SUBFAM_PRI_2H_AXE",
	classification = "CLF_2H_AXE",
	flags        = "FLAG_HASPREVIEWIMAGE",
	weargroup    = "WEARGROUP_INVALID",
	-- 3d model + animation info
	model0Data = {
	  name         = "models/weaponsnpc/orc/n_orc-2h-axe.GR2",
	  user         = "WEARGROUP_DEFAULT",
	},
	-- logic bounding box
  logicBox = {
    minx=-5.377, miny=-23.13, minz=-1.884, 
    maxx=5.377, maxy=23.13, maxz=1.884, 
	},
	dangerclass   = 0,
}
mgr.typeCreate(7742, newItemType);

 

You can then navigate to that location in the graphics zip files to view the model with Grannyviewer and see what its surface.txt entry is named, or sometimes the surfaces will be defined in the itemtype entry itself.

 

If you ever want to add an equipset to the game you have to be sure to increase the values in the line "mgr.reserveEquipsets" at the top of the file to correspond with the increased number of entries.

Link to comment

%USERPROFILE%\AppData\Local\Ascaron Entertainment\Sacred 2\optons.txt

--------

Regarding minion control:

binding_minion_status - pressing the assigned key displays current minion attack mode and distance circle (defines how far will minions veer away from the player in pursuit of hostiles).

binding_toggle_minion_attackmode - pressing the assigned key changes minion attack mode.
binding_toggle_minion_attackrange - pressing the assigned key changes distance circle radius.

 

I'd advice to assign those to NUM '/', NUM '*', NUM '-' respectively:

	binding_minion_status = 74,
	binding_toggle_minion_attackmode = 181,
	binding_toggle_minion_attackrange = 55,
Link to comment
  • 2 weeks later...

"game_directory"\scripts\shared\spells.txt:

--------

​The "cSpellHeFeuerball" spellcass can be used to make hybrid combat arts and, unlike the "cSpellSeSchwertfeuer"(Archangel's Wrath) spellclass, it does not hide projectile hit visual effects.

 

The "et_physical_to_best"(converts physical damage to the least resisted by the target) entry can be used with any weapon or hybrid combat art, perhaps even with spell combat arts.

 

While "cSpellDmVertrauter", "cSpellDmBeschuetzer", "cSpellGenericBuff" permanent buff spellclasses accept the "et_friend_factor"(party buff effect) entry, they only update the state upon recasting. New party members won't receive bonuses, unless the buff is recast.

 

All stock permanent party buff spellclasses, except the aforementioned ones, will add an annoying visual bug(constant weapon glow refreshes), as well as sinusoidally change bonus values for attributes, if the buffs with those spellclasses are given any "et_addattr..." entries. The culprit here is any bonus from blueprint.txt with type = "BONUS_STATS". Another lovely landmine from Ascaron devs. How quaint :Just_Cuz_12: .

 

The eiStateName = "cGarble" used by Ruthless Mutilation, as well as other multiple attack states don't check the proper melee range value for dual magic staves. Any Ruthless Mutilation attack with dual magic staves will hit opponents up to maximum hardcoded range for the second staff, making single-handed magic staves premier weapons for unmodded Inquisitors :sun:

Edited by dimitrius154
  • Like! 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...
Please Sign In or Sign Up