June 18, 2018, 10:56:25 AM

Username
Password

Pages: 1 ... 3 4 [5] 6   Go Down
Print
Author Topic: Enemy units in Campaign  (Read 23313 times)
0 Members and 1 Guest are viewing this topic.
Ghabry
Developer
*
Offline Offline

Posts: 1009



View Profile
« Reply #60 on: March 29, 2012, 08:41:16 PM »

The campaign script is hardcoded in EngRel.exe. It starts at 0x0C1C20 (when you look at the dump thats 0x4C3C20 - 0x402000, the script was dumped while the game was running, the offset defined somewhere in the header of the exe file) (not human readable so you won't see much). It's basicly 4 bytes adress of a function (can be any function that takes 0 arguments) followed by arguments (4 bytes each).
There is currently no tool to edit (or extract) it. Can't find the tool anymore I used to dump it. And nobody ever showed real interest in editing the campaign script. Changing strings e.g. would be also a bit problematic because they are referenced via a pointer.
I could try to write one but also have lots of other things to do so it would take at least a month ^^.
Logged

olly
Global Spokesperson
*
Offline Offline

Posts: 1867



View Profile
« Reply #61 on: March 29, 2012, 09:49:27 PM »

Such a tool would be greatly appreciated, especially in preparation for any future mod maps that will really tie together the advancements in CTL scripts and make truly new campaigns for all the new DOE2 sprite races.

Smiley

Logged

and back in Nuln, the ageing Graf Berhardt smiled his secret smile of pride whenever he heard the latest tales of his eldest son's ever growing chain of glorious victories -(sothr manual)
cuthalion
Campaign Creator
*
Offline Offline

Posts: 370


View Profile
« Reply #62 on: April 02, 2012, 05:47:42 PM »

I am curious how exactly Mork's War Banner works. (never played in multiplayer) I know it instantly destroys mages in melee.
But who are considered mages? Unit type = Dark/Orc/Goblin/Human Wizard?
Or any unit that has a spellbook? In particular, would it destroy Hand of Nagash and Dread King?
Logged
Ghabry
Developer
*
Offline Offline

Posts: 1009



View Profile
« Reply #63 on: April 02, 2012, 07:56:28 PM »

I guess it checks for the mage type but I don't think that this was ever tested. The easiest way to test it would be to give it to any unit in singleplayer (with wh32edit) and then go close combat with the Dread King.
Logged

cuthalion
Campaign Creator
*
Offline Offline

Posts: 370


View Profile
« Reply #64 on: April 03, 2012, 11:53:03 AM »

Indeed,
at least the Dread King feel comfortable in Melee vs Orcs.

Another question I have,
I'm interested in setting up a randomizer - something that would pick up one of 2 or several ways at Random.
I didn't quite get how exactly all those registers - global, unit, - work. and how many private registers may a unit have.
I saw that function set_unit_r_random1to10.

Shall I write something like

blablabla...
set_unit_r_random1to10

test_unit_r_eq_i 1
iftrue
 bla1
else
 test_unit_r_eq_i 2
 iftrue
   bla2
 else
   bla3
 endif
endif

Would it give me 10 options, in first I get 'bla1', in second 'bla2', in all the others - bla3?
Logged
Ghabry
Developer
*
Offline Offline

Posts: 1009



View Profile
« Reply #65 on: April 03, 2012, 12:56:35 PM »

We don't know how many private registers a unit has. Under the assumption that only set_unit_r and similiar functions can write unit registers you can use any register that is not referenced in the CTL. There should be at least 6 registers available per unit, but could be also more (if the number is too high you will overwrite other data).

The set_unit_r_random1to10-command is actually not really random. You don't get a new random number every call. It's actually a counter that is increased from 1-10 and then reset to 1 again. One increment takes around 1 second (not measured) so make sure to have a long delay with e.g. a timer.

Your code looks correct from the structure (bla1 or bla2 are executed in 10% of the cases, bla3 in 80%). But your function calls are wrong.
set_unit_r_random1to10 takes as an argument the register that receives the "random" value.
test_unit_r_eq_i takes two argument (register and value that will be written in the register).

Note that there is no way to compare a range so if you want to do bla when r is 1 or 2 you should write:

test_unit_r_eq_i 1 1
iftrue
 call 42
else
 test_unit_r_eq_i 1 2
 iftrue
   call 42
 else
   test_unit_r_eq_i 1 3
   iftrue
     bla2
   else
     bla3
 endif
endif

And then implement the logic for bla in .func 42 (end the function with a return).
Logged

cuthalion
Campaign Creator
*
Offline Offline

Posts: 370


View Profile
« Reply #66 on: April 03, 2012, 01:34:25 PM »

I see,

What happens if I write

set_unit_r_random1to10 5

and then w/o any delays

test_unit_r_eq_i 5 1
iftrue
 bla1
else
 bla2
endif

do you know if random1to10 start always with 1 and then changes 2,3,4, etc?
If so, then bla1 will be always executed and bla2 - never.
Or can it start say with 6, and then go 7,8,9,10,1,2 etc

Let me explain what exactly I'd like to achieve.
When I finish my campaign, I am unlikely to force myself into another unique campaign like that.
But I'd like to play with own army, and supply it with 1-2 unique units.

As an example, a unit that gets 1-2 spells each mission, but isn't a mage.
I've already checked the possibility and it works fine: it's enough to write a unique CTL script for that unit instead of .func 100, and it will have and will cast those spells I assign to it.
The only problem is to have it pick up that spell at random from a pre-defined list. So is it achievable with that randomizer?
Logged
Ghabry
Developer
*
Offline Offline

Posts: 1009



View Profile
« Reply #67 on: April 03, 2012, 01:53:29 PM »

The (bad) randomizer is always starting with 1 when the map was loaded. But I'm not sure if it's already incrementing the value when you are in deployment phase (test it).
If it is then you can use the time when the player clicked "start game" as a "random" value. (that means make your check after wait_for_deploy and assign the spell there). As long as the player does not use a stop watch to get the perfect click moment this randomness should be enough Wink.
If the randomizer is not incrementing it's value in the deployment phase I don't know how you can generate randomness directly after the deployment phase.

Edit:
For randomness at mission start I guess you will need some clever WHMTG script that generates a random value for you (no idea yet how to do this but should be somehow possible; The game must store the random seed for magic items somewhere in the savefile, when you reload your mage gets the same spells)) and then sets the savegame values for Carstein, Hand of Nagash and Black Grail to 1 or 0. Then you can check it with #d7 at mission start (give you 8 possible combinations (3 fields, value 1 or 0, 2^3 = 8 )).
« Last Edit: April 03, 2012, 02:02:49 PM by Ghabry » Logged

cuthalion
Campaign Creator
*
Offline Offline

Posts: 370


View Profile
« Reply #68 on: April 03, 2012, 03:58:05 PM »

OK, I got it thank you.

I will try the 1st plan when I finish the campaign, and if it fails, let's see what can be done about general game script.
Logged
cuthalion
Campaign Creator
*
Offline Offline

Posts: 370


View Profile
« Reply #69 on: April 05, 2012, 04:38:06 PM »

Ghabry I need your help Smiley once again.

It seemed to me that it's enough to set for 1 of my units start script different from 100 (say 99 or the last enemy script+1 or whatever) and that particular unit will be handled by that script.

But seems I was mistaken and my previous tests were wrong.
Regardless btb value in <13>, all 'my' units start with script 100. They ****ing ignore that value!

So I need means to distinguish between my units (except for unit class that may be the same for 2 or more units) in func 100, if I want a specific logic for my units out there.
For "Unit Id" I found only 'test_unit_alive' which won't help.
As for test_unit_label, all units from func 100 would have the same label.
Maybe there a way to enforce a unique ctl function in btb for units. I've no idea thus far.
Maybe there are other unique flags for each unit?..
Logged
Ghabry
Developer
*
Offline Offline

Posts: 1009



View Profile
« Reply #70 on: April 05, 2012, 05:41:16 PM »

Hm, I only noticed in multiplayer that the script handler is overwritten with .func 100. Didn't knew that singleplayer has the same problem.
We don't know of any function yet that can check the Unit Id or similiar.

Because all unit scripts are executed sequential you could try to assign a label to every unit with a branch:

test_global_r_eq_i 1 0
iftrue
  set_unit_label 12345
  set_global_r_i 1 1
else
  test_global_r_eq_i 1 1
  iftrue
    set_unit_label 12346
    set_global_r_i 1 2

and so on 15 times Wink

As usual untested.
The following assumptions must be correct to get this working:
- The execution order of the unit script must be always the same (otherwise the labels are wrong).
- The default global register value must be 0 (not random)
Logged

cuthalion
Campaign Creator
*
Offline Offline

Posts: 370


View Profile
« Reply #71 on: April 05, 2012, 05:55:18 PM »

I see, will try this out.

Execution order might be the same in all missions or correspond their sequence in BTB file. It may be different but adjustable.

There is no way to check unit flags like 'goblin flag', 'will never toute' etc is there?

BTW You suggest that I use this or that register. Are there 'untouchable' registers that are usually used in other scripts and shouldn't be altered by me?

Logged
Ghabry
Developer
*
Offline Offline

Posts: 1009



View Profile
« Reply #72 on: April 05, 2012, 06:08:06 PM »

BTW You suggest that I use this or that register. Are there 'untouchable' registers that are usually used in other scripts and shouldn't be altered by me?
Our current theory is that all registers that are not referenced in the CTL file are save to use. Nobody proofed this wrong yet...

And nope we don't know how to read the unit flags.
Logged

cuthalion
Campaign Creator
*
Offline Offline

Posts: 370


View Profile
« Reply #73 on: April 05, 2012, 06:24:25 PM »

Found a few ways around but nothing fully satisfactory yet.

   test_other_unit_selected 2
   iftrue
    #9d 30
   endif

If set in func 100 prior to deploy, gives Conflagration to Gunther Schepke if I order them a command before deployment (move or attack)
If set in func 100 right after deploy, gives Conflagration to Gunther Schepke, but only if he is selected by the moment I click Deploy.
Logged
cuthalion
Campaign Creator
*
Offline Offline

Posts: 370


View Profile
« Reply #74 on: April 05, 2012, 06:38:51 PM »


test_global_r_eq_i 1 0
iftrue
  set_unit_label 12345
  set_global_r_i 1 1
else
  test_global_r_eq_i 1 1
  iftrue
    set_unit_label 12346
    set_global_r_i 1 2

and so on 15 times Wink


This works, at least on B101.

The sequence doesn't depend on btb file, and always returns the same order: Cavalry, Infantry, Xbows, Cannon.

I will test it further in order to realise if the order equals to the order of troops in the Army Roster, or if it equals to ascending Unit Ids. That is about the same though. So probably it will be more or less the same throughout the campaign and thus can be copy-pasted from ctl to ctl. Will report further.

It won't work if I lose a unit though. And my favourite tactics of destroying Black Grail is find an unhappy infantry like Night Goblins in Goblin Adventures and give it Defiance+Heart of Woe Smiley

Modify Message
Yes it's simple troop roster sequence.
Imperial Tank before the last mission breaks in in the middle, and there is also a problem if a unit is lost. The rest of the campaign will be screwed up.
« Last Edit: April 05, 2012, 07:25:12 PM by cuthalion » Logged
Pages: 1 ... 3 4 [5] 6   Go Up
Print
Jump to: