Jump to content

ESP: The beginning and the modmerging system [S2G/CP1.6/EE2.1/SS,C]


Recommended Posts

2 minutes ago, dimitrius154 said:

Creating animation sets while using duplicate [itemtype] entries won't pose a problem. Using duplicate [base] entries would result in the newer animation set overriding the previous for any creature, weapon, or armor that fist the [base] entry mask. 

Here is an example. The setup file gets checked for each [base], then overwrites exisiting [base] entries in the target file, or appends them if they dont exist. Should the program additionally check whether [itemtype] of the setup file has a unique id in the target file ?

Link to comment
40 minutes ago, Charon117 said:

Should the program additionally check whether [itemtype] of the setup file has a unique id in the target file ?

Once I remove all the duplicate entries from the animation.txt, which should not take long, probably not.

Link to comment

So ... ... .... Soooooooooooo ... ... Soooooooooooooooooooooo ...

I have a lot of undefined behaviour in my program. And as I was saying the modmerge system preserves the build underneath as much as it can. Turns out that the modmerge system assumes that the animation.txt is a "clean" build, that is it doesnt contain dublicates of [base].

To put it simply, the CP has a dirty animation.txt.

I would like to discuss with everybody how to solve this problem. I won´t make a modmerge system ontop of broken stuff.

(1) The best solution ofcourse would be a recompilation of the CP installer. The double hit spell damage for the boss golem needs to be fixed anyway. This is the best solution because people who dont know a lot about modding will not be bothered with a 1000 steps guide.

(2) The second best solution. Actually release a good, fixed CP patch for CP 1.6. Put it directly beside the download, with RED BIG letters saying its NECESSARY.

(3) I am most in favour of this suggestion. Since (1) is mostly not to be expected, and (2) is susceptible to inattentive users, I would simply suggest that the Modmerge System automatically removes dublicated [base] entries. This kind of goes against the philosophy of "preserving the build underneath it as much as possible" but I dont think most people will be bothered by the fact that their animation.txt gets cleaned up, if it is true that only the last [base] entry gets taken. I will however softcode that function for users to choose from, to not deviate from the iron principle of preserving the build underneath.

 

Although, that will be for another day.

Link to comment

I actually wanted to include the fixed EE and Addendum animation.txt but then I realised that you propably have later versions of those. So if you @Flix @dimitrius154 want to send in your animation.txt, than the bot can automatically clean them.

 

On to the actual news.

The modmerge system now takes the animation.txt and

  • Removes dublicates in the target file, and trims multi-new-lines to single new lines.
  • Modmerges content based on the unique identifier [base].
  • And as a bonus it makes sure that the modmerged [base] entries have unique [itemType] IDs in the target file.

A word of advice though, as I found out the modmerge file doesnt take dublicated [base] entries in succession, and it crashes the modmerge system. Now that isnt a problem because the modmerge file shouldnt contain dublicated [base] entries anyway, but on paper the modmerge system also shouldnt have a problem with them. I couldnt find and fix this issue.

Edited by Charon117
Link to comment
1 hour ago, Charon117 said:

want to send in your animation.txt, than the bot can automatically clean them

Attached for EE and D2F.

How does it decide which ones to delete? What if one entry has more animations defined than another?

animation.zip

Link to comment
3 minutes ago, Flix said:

How does it decide which ones to delete? What if one entry has more animations defined than another?

 

Load animation.txt into vector line by line
Check every line ( vector element ) for element [\"base\"]
if element has [/"base/"] then
   Load element vector into variable ( eg. "    ["base"] = "models/heroes/seraphim/c_sera_skin//sfafsdfdsfsfsdssd","
   Check Vector again line by line if [base] variable matches any line excluding the the original one
   if it finds one then
      Find Upper Delimeter AnimInfo = { for the original entry
      Find Lower Delimeter mgr.addAnimInfo(AnimInfo) for the original entry
      delete Vector elements by iterator between upper and lower delimeter
   else do nothing

Lastly trim away multi-new lines to single ones.

Lets say if you have 6 orc banner dublicates. It first finds the first one, and then checks if it finds a dublicate and finds number 2. Then it deletes entry 1. >> Finds 3 deletes 2, Finds 4 deletes 3. Finds 5, deletes 4. Finds 6 and deletes 5. The endresult is number 6.

 

Code

if(SAniDelDub2 == "Yes"){

std::cout << "\n\tDublicated [base] entries are getting removed.\n" << std::endl;



std::vector<std::string>::iterator itDB = VFileB.begin();

unsigned long long itDB2 = 0;

unsigned long long itDB3 = 0;

std::vector<std::string>::iterator itDB4;

std::vector<std::string>::iterator itDB5;

std::vector<std::string>::iterator itDB6;

std::vector<std::string>::iterator itDB7;

bool NoDublicate;



while(itDB != VFileB.end()){

itDB3 = VFileB[itDB2].find("[\"base\"]");



if(itDB3 < 1000000){

for(NoDublicate = false; NoDublicate == false;){

itDB4 = std::find(VFileB.begin(), VFileB.end(), VFileB[itDB2]);

itDB5 = std::find(itDB4 +1, VFileB.end(), VFileB[itDB2]);



if(itDB5 != VFileB.end()){

for(FoundDelimeter = false, itDB3 = itDB2; FoundDelimeter == false; --itDB3){

if(VFileB[itDB3].find(KUDelimeter) < 100000000){ // allows for a 100kk lines of code, currently animation.txt has 130k lines of code

itDB6 = VFileB.begin() + itDB3;

FoundDelimeter = true;

}

}



for(FoundDelimeter = false, itDB3 = itDB2; FoundDelimeter == false; ++itDB3){

if(VFileB[itDB3].find(KLDelimeter) < 100000000){ // allows for a 100kk lines of code, currently animation.txt has 130k lines of code

itDB7 = VFileB.begin() + itDB3;

FoundDelimeter = true;

}

}



std::cout << VFileB[itDB2] << " dublicate has been removed." << std::endl;

VFileB.erase(itDB6, itDB7 + 1);



//getchar();

}



if(itDB5 == VFileB.end()){

NoDublicate = true;

}

}

}



++itDB;

++itDB2;

}

}

 

Link to comment
2 hours ago, Charon117 said:

want to send in your animation.txt, than the bot can automatically clean them

Not yet. I've done the cleaning for the entries mentioned before and, as I add unique models for weapons and armor, I add animations for some of them. 

Link to comment
1 hour ago, Charon117 said:

Please check if they work, as I dont have the capability to do so.

Running a compare doesn't show anything important missing.

EE version runs fine at least. 

Link to comment

@Flix Congrats on the release of EE 2.2.

 

 

 

 

Ontopic: If there is enough interest I can release the cleaning tool for the animation.txt as a standalone utility tool.

 

Continuing with the files:

  • collision.txt
  • Eliza.txt
  • environment.txt

Is there anything I need to know about these files ?

Cheers

  • Thanks! 1
Link to comment

Update: I fixed the animation.txt code, as it was completely broken. As a side effect the modmerge system doesnt have a problem with dublicated [base] entries in the modmerge file anymore.

 

Again, I scanned the collision.txt and found a huge number of dublicates. List is down below. Can someone confirm what happens with the dublicates, and whether its (1) safe to delete them ? Does the last entry get used like in the animation.txt ? And most importantly should modmerge system (2) overwrite unique entries or (3) simply append all entries at the bottom ?

collision dublicates:

 

mgr.colvolCreate("models/questitems/t_scifi-switch",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-1",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-a",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-b",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-c",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-d",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-e",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-f",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-g",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-1",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-a",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-b",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-c",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-d",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-e",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-f",colvol)
mgr.colvolCreate("models/objects/stones/d_fels-wand_02-g",colvol)
mgr.colvolCreate("models/objects/mines/h_orepile-silver01",colvol)
mgr.colvolCreate("models/objects/mines/h_orepile-silver02",colvol)
mgr.colvolCreate("models/dungeon/d_stdungeon_stoneheap01",colvol)
mgr.colvolCreate("models/dungeon/d_stdungeon_stoneheap02",colvol)
mgr.colvolCreate("models/dungeon/d_stdungeon_stoneheap03",colvol)
mgr.colvolCreate("models/objects/stationery/h_map",colvol)
mgr.colvolCreate("models/objects/stationery/h_map",colvol)
mgr.colvolCreate("models/objects/stationery/h_map",colvol)
mgr.colvolCreate("models/objects/stationery/h_map",colvol)
mgr.colvolCreate("models/objects/stationery/h_map",colvol)
mgr.colvolCreate("models/objects/stationery/h_map",colvol)
mgr.colvolCreate("models/objects/stationery/h_map",colvol)
mgr.colvolCreate("models/objects/stationery/h_map",colvol)
mgr.colvolCreate("models/objects/mines/h_orepile-silver01",colvol)
mgr.colvolCreate("models/objects/mines/h_orepile-silver02",colvol)
mgr.colvolCreate("models/objects/mines/h_orepile-silver01",colvol)
mgr.colvolCreate("models/objects/mines/h_orepile-silver02",colvol)
mgr.colvolCreate("models/objects/mines/h_orepile-silver01",colvol)
mgr.colvolCreate("models/objects/mines/h_orepile-silver02",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot1",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot3",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot7",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot20",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot1",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot3",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot7",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot20",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot1",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot1",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot1",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot3",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot3",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot3",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot7",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot7",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot7",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot20",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot20",colvol)
mgr.colvolCreate("models/objects/jeweler/t_ingot20",colvol)
mgr.colvolCreate("models/objects/misc/t_clothheap02-messed",colvol)
mgr.colvolCreate("models/objects/misc/t_clothheap03-messed",colvol)
mgr.colvolCreate("models/objects/misc/t_clothheap02-messed",colvol)
mgr.colvolCreate("models/objects/misc/t_clothheap03-messed",colvol)
mgr.colvolCreate("models/objects/misc/t_clothbale01",colvol)
mgr.colvolCreate("models/objects/misc/t_clothbale01",colvol)
mgr.colvolCreate("models/objects/misc/t_clothbale01",colvol)
mgr.colvolCreate("models/objects/misc/t_clothbale01",colvol)
mgr.colvolCreate("models/objects/misc/t_clothbale01",colvol)
mgr.colvolCreate("models/objects/signs/d_wegweiser-01a",colvol)
mgr.colvolCreate("models/objects/signs/d_wegweiser-01b",colvol)
mgr.colvolCreate("models/objects/signs/d_wegweiser-01c",colvol)
mgr.colvolCreate("models/objects/signs/d_wegweiser-01d",colvol)
mgr.colvolCreate("models/objects/signs/d_wegweiser-01e",colvol)
mgr.colvolCreate("models/objects/signs/d_wegweiser-01a",colvol)
mgr.colvolCreate("models/objects/signs/d_wegweiser-01b",colvol)
mgr.colvolCreate("models/objects/signs/d_wegweiser-01c",colvol)
mgr.colvolCreate("models/objects/signs/d_wegweiser-01d",colvol)
mgr.colvolCreate("models/objects/signs/d_wegweiser-01e",colvol)
mgr.colvolCreate("models/dungeon/d_stdungeon_stoneheap01",colvol)
mgr.colvolCreate("models/dungeon/d_stdungeon_stoneheap02",colvol)
mgr.colvolCreate("models/dungeon/d_stdungeon_stoneheap03",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-a1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-c1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-d1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-e1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-g1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-i1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-j1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-k1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-a1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-c1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-d1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-e1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-g1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-i1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-j1",colvol)
mgr.colvolCreate("models/objects/stones/lizards/l_lizsteingross-k1",colvol)
mgr.colvolCreate("models/objects/stationery/d_book01",colvol)
mgr.colvolCreate("models/objects/stationery/d_book01",colvol)
mgr.colvolCreate("models/objects/stationery/d_book01",colvol)
mgr.colvolCreate("models/objects/stationery/d_book01",colvol)
mgr.colvolCreate("models/questitems/t_scifi-switch",colvol)
mgr.colvolCreate("models/objects/misc/mg_tft01",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-citizen-kadaver1",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-citizen-kadaver2",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-citizen-kadaver3",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-citizen-kadaver4",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-soldier-kadaver1",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-soldier-kadaver2",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-soldier-kadaver3",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-soldier-kadaver4",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-w-citizen-kadaver1",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-w-citizen-kadaver2",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-w-citizen-kadaver3",colvol)
mgr.colvolCreate("models/objects/corpses/j_viking-kadaver1",colvol)
mgr.colvolCreate("models/objects/corpses/j_viking-kadaver2",colvol)
mgr.colvolCreate("models/objects/corpses/j_viking-kadaver3",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign1",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign2",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign3",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign4",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign1",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign1",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign1",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign1",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign2",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign2",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign2",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign3",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign3",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign3",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign4",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign4",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign4",colvol)
mgr.colvolCreate("models/objects/signs/housesigns/z_housesign4",colvol)
mgr.colvolCreate("models/objects/misc/mg_tft01",colvol)
mgr.colvolCreate("models/objects/misc/mg_tft01",colvol)
mgr.colvolCreate("models/objects/misc/mg_tft01",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-citizen-kadaver1",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-citizen-kadaver2",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-citizen-kadaver2",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-citizen-kadaver3",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-citizen-kadaver3",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-citizen-kadaver4",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-citizen-kadaver4",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-w-citizen-kadaver1",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-w-citizen-kadaver2",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-w-citizen-kadaver3",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-w-citizen-kadaver1",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-w-citizen-kadaver2",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-w-citizen-kadaver3",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-soldier-kadaver1",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-soldier-kadaver2",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-soldier-kadaver3",colvol)
mgr.colvolCreate("models/objects/corpses/j_hu-m-soldier-kadaver4",colvol)
mgr.colvolCreate("models/objects/corpses/j_viking-kadaver1",colvol)
mgr.colvolCreate("models/objects/corpses/j_viking-kadaver2",colvol)
mgr.colvolCreate("models/objects/corpses/j_viking-kadaver3",colvol)

Edit: Eliza.txt doesnt have any dublicates.

Edit2: Environment.txt doesnt have dublicates either. I will start to work on Eliza.txt and Environment.txt until somebody can tell me what to do with the dublicated entries in collision.txt.

Edited by Charon117
Link to comment
4 hours ago, Charon117 said:

what happens with the dublicates, and whether its (1) safe to delete them ? Does the last entry get used like in the animation.txt ?

Those don't look like duplicate entries: their "box0", "box1" arrays don't match. Therefore, they should not be tampered with.

Link to comment

@FlixI would like to talk about something I have been noticing for a while and which bothers me a bit about the game.

CP is nice. EE is nice. Challenge mode is nice. But there was something in vanilla which I thought was quite a bit better. And that is the visual representation of danger and strenght of mobs in comparasion to each other. Here are a few points.

  • Removing the yellow glow was propably necessary to display the unique elite textures, but it also removed the danger signal from those enemies. Running around in vanilla made you instantly realise how many elites were charging at you, making you able to reliably and consistently judge in how much danger you were at any given moment. I already wrote about how I have immense difficulties to differentiate between champions and mobs, and looking at 20 units charging at you gives me zero information about the composition of the mob. While the yellow glow wasnt the prettiest, it got its job done to create danger signals way better than elite textures which players can hardly differentiate, and definitely not at a glance.
  • I heard that in I&B the champions got buffed, to be more differentiated than normal mobs. While this might mostly be a good change, the visual representation of the gained strenght is lacking. Melee attacks, ranged projectiles and model textures pretty much stayed the same to normal ones.
  • Spells visuals are indifferentiated and dont tell you something about their strenght. For instance a normal ogers ice field is exactly the same as a champions one. All young dragonlings fireballs look the same. There is no visual telling between each dragon bosses fire attacks. They all look pretty, but the most important component in an ARPG, the visual danger element, is sorely lacking.
  • The same applies to ranged attacks from normal mobs to champions. Zero difference.

 

So my wishlist for the shared effort between EE, Addendum, D2F and CP is that the signalling of "danger" is visually improved. Small attacks should look and feel like small attacks, while a big firebal should be a dangerous one. Im not asking for things to be made flashier, I asking for flashier visuals for stronger attacks. Here are a few of my suggestions:

  • Add an aura to champions, which lets you immediatelly tell whether that particularly enemy is stronger than a normal one.
  • Differentiate spells and make the player see the difference between a strong, and a weak spell. Make the projectiles bigger, or flashier or implement a signal that differentiates it from normal mob ones.
  • If a mob uses a CA make the weapon glow differently, to signal a stronger attack. Same for projectiles which are cast by CA.
  • Maybe something can be done for melee attacks ?
  • Rework bosses danger visuals, to be comparable to each other.

 

All of that is ofcourse a long shot, but I wish that modding effort would go into the direction of a better distinguishable danger map of the game.

Since I have a lot of other things to do, and lack the experience of modding the game these things will never be done by me, as I lack the time and skill to do it. But I would still appreciate such things done to the game.

Link to comment
37 minutes ago, Charon117 said:

the signalling of "danger" is visually improved.

Like they do in the Elder Scrolss series, eh? Problem is, in Elder Scrolls, ever since Morrowind, visuals have been model based. You could create basically any visual effect, provided you had the skill to implement it within the nif format. In Sacred 2 all visual effects are:

1) Strictly defined within the code, thus we have a limited selection

2) Applied by the code, with extra quirks to boot

3) Can interfere with each other. The most outrageous example, as of now, is ice enchatment shader making any surface with SURFACE_FLAG_TRANSPARENT flag enable invisible.

Link to comment
4 minutes ago, dimitrius154 said:

Like they do in the Elder Scrolss series, eh?

Havent played too much of it to answer that. What I have in mind are visual cues for the player to take notice of. An example for the glow on attack would be the heavy attack of the Kraken, where the arms start to glow before he smashes down.

The aura or miasma for creatures can look like this:

 

For the other questions I dont have an answer. I will leave that in more capable hands than mine.

Link to comment
2 hours ago, Charon117 said:

Add an aura to champions, which lets you immediatelly tell whether that particularly enemy is stronger than a normal one.

The "hacky" way I can think of doing what you're actually asking would be to give every single elite enemy the AI to cast a buff on itself, and then assign it a specially created buff in creatures.txt. Said buff would be created in spells.txt to have no actual properties on it, it would just serve to provide a visual aura.

In D2F I tried to signify elites through model changes, model scaling (bigger = stronger), or texture changes.  What I wanted to do is revamp the spawn.txt pattern of having an elite enemy lead a mob, and instead have champions spawn in their own separate packs like in D2.  The sheer work behind that would be insane though. Literally every spawn entry would have to be edited.

Link to comment
12 minutes ago, Flix said:

The "hacky" way I can think of doing what you're actually asking would be to give every single elite enemy the AI to cast a buff on itself, and then assign it a specially created buff in creatures.txt. Said buff would be created in spells.txt to have no actual properties on it, it would just serve to provide a visual aura.

The buff would only get cast once the AI notices the player, at which point its prolly too late anyway.

12 minutes ago, Flix said:

In D2F I tried to signify elites through model changes, model scaling (bigger = stronger), or texture changes.  What I wanted to do is revamp the spawn.txt pattern of having an elite enemy lead a mob, and instead have champions spawn in their own separate packs like in D2.  The sheer work behind that would be insane though. Literally every spawn entry would have to be edited.

I like the "bigger" idea. If a champion is only slightly bigger than its normal counteraprt than that would be immediatelly recogniseable. We are humans after all, and size matters to us, which is why even small differences would be quite noticeable. I hope the insane amount of work only concerns the rework of the spawn.txt.

Also, dont do anything I could do. My bots and programs can usually run through such things effortlessly, as soon as I understand the structure. I cant change models, but text files are no problem to me. Even with half a million code lines its easy once you get a repeatable pattern.

Edited by Charon117
Link to comment

Model scaling is easily done through creatures.txt.  Let's take an example:

mgr.createCreature {
	id = 50,
	itemtype_id = 2524,
	name = "Barb_cobold_mage_elite",
	behaviour = "Enemy_mage",
	dangerclass = 4,
	groupmaxcount = 1,
	elite_creature_id = 52,
	probabilityforelite = 0.000000,
	rank = 90,
	tenergy_creature_id = 258,
	template_creature_id = 1200,
	livesremaining = 0,
	unconscioustime = 5,
	palettebits = "1111111111111111",
	monstertype = 1, -- designates the enemy as elite, 0 is normal, 2 is boss
	faction_id = 37,
	equipset_id = 61,
	modelscale = 1.100000, -- You can see here that elite Kobolds are already scaled slightly larger than the normals which would be at 1.000000
	rise_from_ground = 0,
	has_corpse = 1,
	has_soul = 1,
	can_strafe = 0,
	spells = {
		entry0 = { "enemy_pestball" },
		entry1 = { "enemy_spawn_erdele_small" },
	},
}

So all you'd need to do is use whatever unique identifier you want to use to comb through entries, and then look at every entry with monstertype = 1, then change the modelscale line in such entries to be something bigger, perhaps 1.25 or even 1.5. 

  • zomgod! 1
Link to comment

I mean, when you think of it the elite textures do help because the elite model is usually different (you can easily spot an ogre champion with its yellow robe), but I reckon that having the models slightly bigger would seem visually more appealing because you'll see an elite walking taller than the pack. So I think it's a cool idea, even for vanilla gameplay.

Link to comment

Honestly they already are bigger, just apparently not enough for people to notice.  Almost all elites except for Humans and High Elves have at least 1.1x scaling.

1.25x might be more appropriate to make it obvious at a glance.  I'd advise against making Kobolds much bigger than that as they start to look ridiculous with their proportions.  Someone once asked me to make them much bigger so they could see them in the tall grass (they were often hidden in the grass), and they looked both hilarious and terrifying with their giant heads.

Link to comment
  • The title was changed to ESP: The beginning and the modmerging system [S2G/CP1.6/EE2.1/SS,C]

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