May 28, 2017, 12:00:47 AM

Username
Password

  Show Posts
Pages: [1] 2 3 ... 65
1  Warhammer Dark Omen / Help Section / Re: application unable to start correctly on: May 22, 2017, 04:41:13 PM
First isolate if it's ddraw.dll or darkpatch.dll. Does original PRG_ENG start with ddraw.dll in the folder?

Does modded PRG_ENG work without ddraw.dll in the folder?

Otherwise it must be darkpatch.dll. Though no idea what the problem is then, have no Windows 8 :/
2  Warhammer Dark Omen / Help Section / Re: application unable to start correctly on: May 10, 2017, 10:54:44 PM
I analyzed this error two weeks ago because I had no setup available and the same issue.

Go to "Programs and Features" and click "Add/Remove Windows Features".
And under "Outdated/Inherited components" (No idea how it is called in English) tick "DirectPlay".

Accept the changes and DO should start.
3  Modifications / Maps / Re: Custom CTL OpCodes on: May 05, 2017, 05:20:28 PM
Global CTL functions sounds interesting. Conviniently Dark Omen has one function to do the function number -> address mapping so in theory it should be feasible to simply parse a 2nd CTL file which contains "global functions" and then to hook this lookup function... Will check how hard this is.
4  Modifications / Maps / Re: Custom CTL OpCodes on: May 04, 2017, 04:52:43 PM
Aaah, yeah. That stuff. Was documented here: http://wiki.dark-omen.org/do/Talk:DO/ARM#Unit_Type_Bitfield

Okay so CTL had only a unit type but no race check. good.
5  Modifications / Maps / Re: Custom CTL OpCodes on: May 01, 2017, 11:24:33 PM
Olly your requests are probably too complex for single opcodes. That should be achievable through smart ctl usage I assume.

Cuthalion: proper random is easy to add Smiley
Guess I could also provide old opcodes which take a register argument instead of only constants, will add more flexibility (e.g. for addmagic)
How is the unit race specified in wh32edit?
6  Warhammer Dark Omen / Help Section / Re: 3D mode and Win8/7 [ Dark Omen ] on: May 01, 2017, 11:10:02 AM
Never heard about pcem. Interesting tool for old games Smiley
7  Modifications / Maps / Custom CTL OpCodes on: April 30, 2017, 06:38:44 PM
The latest version of the "Mod Selector" added support for custom CTL commands. To use them you need the latest version of ctldis, too.

Currently implemented commands:

set_deployment_limit n - Sets the deployment limit on this map to "n". Call before "wait_for_deploy" in .func 100.

Any ideas for further commands?
8  Modifications / Tools / Re: Mod Selector on: April 30, 2017, 06:21:31 PM
Well I meant that you have to remove the ddraw.dll of aqrit which provides XSlots because our codes conflict now.

So ddraw.dll is free for other things like this dgvoodoo lib.
9  Warhammer Dark Omen / Singleplayer / Re: Further CTL investigation on: April 30, 2017, 04:44:16 PM
Updated ctldis again. Together with the latest version of the Mod selector (released today) you get the new opcode

set_deployment_limit n. Where n is obviously a number of how many units are allowed to be deployed.

Put it in .func 100 anywhere before "wait_for_deploy" obviously.
10  Modifications / Tools / Re: Mod Selector on: April 30, 2017, 02:49:12 PM
Update!

Download

This version merges aqrits changes provided by his ddraw.dll into darkpatch.dll

This means: Delete ddraw.dll before running EngRel otherwise bad things will happen!

XSlots works now without restarting Dark Omen after switching a mod (at least I think so, tell me if you observe any unexpected behaviour).

New: Custom handler for CTL OpCode 0xf1, see the CTL thread.
11  Warhammer Dark Omen / Singleplayer / Re: Further CTL investigation on: April 29, 2017, 03:02:25 AM
Assembling works now.

Annotating should be mostly complete. There are still some empty dicts (e.g. "Voice" for all the audio stuff) or almost empty (e.g. events) dicts. Feel free to fill them and to post them here so I can add them to the script.

You find this at line 460+.

Ignore game_status and alignment, I fill them later.

Please also take a look at the new scripts and try to figure out what some Unit and Control Flags could be. I have notes about them but most of them are uncertain, so want to see others opinion before I add my flawed data.

Edit: Have to recheck arguments of type "ID. Some of them actually check the UnitID, not an incrementing number (enemy+ally). But thats just a visual issue, doesn't impact the functionality
12  Warhammer Dark Omen / Singleplayer / Re: Further CTL investigation on: April 27, 2017, 12:26:35 AM
Added now all known OpCodes to ctldis and type annotated all OpCodes (still without assembler, I add the assembling during the next days). Feel free to make suggestions.

Annotation is still incomplete, more to come.

What is already in:

X() means the argument is unused
E() means the argument is an event
F() means the argument is a function

Example output:

on_event E(71)
   event_test_any_friend_collects_this_item
   iffalse
      event_test_distance_and_collect_this_item 240
      set_return_func_iftrue F(137)
   endif
   end_event Filter



.func 0
    init_unit X(128)
    clear_ctrl_flag 0x8000
    set_label 0xabc0
    #3c 240, X(0)
    set_event_handler F(14)
    set_callback 13, 29
    set_global_r_i 0, 0
    set_global_r_i 1, 0
    wait_for_deploy
    save_ip
    find_and_collect_item Treasure_Chest_100gc
    set_timer 25
    wait_for_timer
    play_self 64
    reset_call_stack
    save_ip
    do
        wait_unit_flag3_clear CollectingItem
        find_and_collect_item Treasure_Chest_100gc
        iffalse
            find_enemy_uflag_attrib E(4), 0, EngineOfWar
            iffalse
                test_unit_flag3 0x400
                iffalse
                    add_waypoint 99
                endif
            endif
        endif
        set_timer 10
        wait_for_timer
    always



on_event E(69)
   event_test_item Treasure_Chest_100gc
   iftrue
      test_event_from_enemy
      iffalse
         test_global_r_eq_i 1, 1
         iffalse
            play_self 66
            set_global_r_i 1, 1
         endif
      endif
      broadcast_event_to_friends E(17)
   endif
   event_test_unit_collects_this_item
   iftrue
      test_event_from_enemy
      iftrue
         test_can_fight_and_sender_does_not_retreat
         set_return_func_with_restart_iftrue F(127)
      else
         set_return_func F(134)
      endif
   endif
   end_event Filter


That "can fight and sender doesn't retreat" appears to make sense because 127 contains:


.func 127
    #14 4, E(-1)
    send_event_to_stored_unit E(20)
    wait_unit_flag1_clear 0x8 | 0x4000
    play_self 1
    #48
    #4f
    do
        for 2
            set_timer 10
            test_target_in_charge_range
            goto_iftrue F(129)
            wait_for_timer
            test_unit_flag1 0x10
            iftrue
                restore_ip
            endif
        next
        #49
    always

.func 129
    charge_and_send_event_to_target ; event 7
    iftrue
        play_self 2
        #14 19, E(-1)
        do
            sleep
            #b0 0
            test_unit_flag1 0x10
        whilenot ; I guess this loop tests if the charge is finished.
    endif
    goto F(134)
13  Warhammer Dark Omen / Singleplayer / Re: Further CTL investigation on: April 26, 2017, 11:28:03 AM
The script is now python 2 compatible. Fixed two issues in it.

Leilond: In case you want to do some prettifying and you know Python take a look at line 326 where the prettifier-dict starts.

The mapping is basicly: opcodename -> [dissasembler, assembler] (so list of 2 elements)

Ignore the assembler for now, they are unused and stubs.

The API is basicly:
The dissasembler and assembler are functions that except as many arguments as the opcode arguments has (so for all prettifiers by now it's only one arg) and the return value is a list of strings with as many list elements as the opcode argument has. So quite simple API to extend.

And Prettifier.flag_prettifier(flag, Prettifier.unit_flag_1) is a helper function which takes an op-code argument as 1st argument and a lookup-dict (see Prettifier.unit_flag_1 for an example) and returns a String with all bits (if posible substituted) and delimited by "|".

Oh and the OpCodes are not up-to-date yet. I have to sync them with the latest observations of the latest days first.

More stuff I want to prettify which doesn't need BTB/ARM parsing so is faster to implement and to make the "data types" of CTL arguments more clear:

  • play (sound effects)
  • spells
  • unit types
  • btb node arguments (e.g. n1 instead of 1)
  • event arguments (e.g. e1 instead of 1, for events that are clear this could be also changed to e.g. E_Charge)
  • function arguments (e.g. f1 instead of 1)
  • control flag (though there is almost nothing known about it)
  • label resolving (should work because every enemy only has one label)
  • end_event 6844 and 3567
  • that @0xABC event marker
  • Nice to have: Annotate functions with the enemy that executes them (needs BTB & ARM parsing)

Maybe should also provide some constant for "registers", e.g. that "-278" register cuthalion uses in his code to read the unit id of a regiment Cheesy (awful hack I told him because the register functions don't do range checks. But you can only read 32bit values with this)

Shame that there is no function to write registers in registers. This way you could do arbitrary loads and abuse unit_flags for bit operations. Cheesy
14  Warhammer Dark Omen / Singleplayer / Re: Further CTL investigation on: April 25, 2017, 07:05:55 PM
I'm currently in the process of updating ctldis with the latest investigations and some prettifiers to get better output: https://github.com/Ghabry/ctldis

Also added Python 3 compatibility Smiley

e.g.:

clear_attribute ContainFanatics
instead of
clear_attribute 2097152

or

test_unit_flag1 Retreat | 0x8000
instead of
test_unit_flag1 40960
15  Warhammer Dark Omen / Singleplayer / Re: Further CTL investigation on: April 23, 2017, 07:31:03 PM
Thanks for your observations. About search and attack enemy did you see my post in this thread from 2 years ago? Based on my latest findings I'm updating the table:

Code:
                            distfunc unittype vision nth  dist uflag1 attribs op
find_enemy_uflag_attrib      0        0        0      1    100  arg2   arg3    a2
find_enemy_visible           0        0        1      1    100  0      0       a3
find_enemy_simple            1        0        0      1    100  0      0       a4
find_enemy_simple_visible    1        0        1      1    100  0      0       a5
find_enemy_unittype          0        arg2     0      1    100  0      0       a6
find_enemy_unittype_2        0        arg2     0      1    100  0      0       a7
find_enemy_nth               0        0        0      arg2 100  0      0       a8
find_enemy_nth_visible       0        0        1      arg2 100  0      0       a9
find_enemy_unittype_nth      0        arg2     0      arg3 100  0      0       aa
find_enemy_unittype_nth_2    0        arg2     0      arg3 100  0      0       ab
find_enemy_distance_uflag    4        0        0      1    arg2 arg3   0       ac

All of them generate arg1 as an event.

- distfunc: Looks like 0 is the direct (diagonal) distance, 1 just considers x or y (bounding box I guess), 4 is some smart thing that considers terrain e.g. (probably useful for archers).
- unittype: Unittype that the searched unit MUST have.
- vision: When 1 the vision of the caller is considered (worse when walking or fighting), except if you have 360° vision (spider) they always find everything
- nth: Not completly sure, my guess is the list of found regiments is sorted and then the n-th regiment is picked (where 1 = the closest)
- distance: Search distance used for the distfunc (not sure how big a 100 is)
- uflag1_xtra: Unit Flag 1 bits that searched unit most NOT have, inactive/retreating and similiar units are never found
- attribute: Attributes that the searched unit must NOT have, e.g. 4096 = engine of war

Also want to clarify other opcodes:
test_event_from_close_combat
This is slightly incorrect. That field is already populated when you select the enemy as a attack target.
Also archers/artillery use the same field to mark the target
so more correct is maybe "test_event_from_target"?

#5c: General purpose retreat
#5b: Same as #5b, considers the target (probably to invert the direction)
#5d: Same as #5c, inverts the retreat dir (needs test if forward or backward)

#86: This one is extremely similiar to #44. I would call this one "test_unit_can_fight" because #44 has an extra feature:
#44: Same as #88 but also checks if the sender of the last event is retreating (and returns false in that case)
#9f: Same as #86 (yeah, really)

#5a: General purpose charge (already named OP_charge)
You said #58 is a test if the enemy is in charge range. This seems legit.
#59: This sends event 7 to the unit being charged

According to my notes wait_unit_flag3_clear 8192 is "Walks to magic item", your question helped me to investigate the op-codes that are around it:

#d0: find_and_collect_item. arg1 is item to find (in the trading post they collect treasure 100)
#d1: only used when d4 is true: Takes the distance (func arg1) of magic item event-arg2. And returns TRUE and collects it when close enough.
#d2: Check if the unit currently collects an item and if the item matches event-arg2
#d3. This is already called test_event_arg3. Could be renamed: This checks if event-arg3 of the last event matches arg1 but this is in the magic item opcode group, so: It is only used in event 69. So 69 is very likely item dropped.
#d4: Only used with event 71, whatever that is. #d4 checks if any regiment in our party is already collecting the magic item specified in event-arg2 (which is an index in some struct) (TRUE if any)

everything after a "return" is dead code

#14: This is some multi-purpose crap. Depending on arg1 it can do 16 (!) different things. The 2nd argument is an event id. And the field of the regiment structure it works on is not documented by me yet. But because you said it is related to fighting I will trigger a fight and check in the debugger to see what it contains, maybe the ref to the enemy being fighted...

#3e registers a timer function for invoking #14 >.<
arg 1: arg to pass to 14
arg 2: run every nth script update

It is worth playing around with "#3c 240, 0" because the 1st arg is used as some distance for most of #14.

BACK TO #14:

I see 10, 12, 13. 12 for peasants. 13 for enemy. 10 for friends.

10 is related to fanatic releasing and generates event 78 which is obviously fanatic spawning.

12 is a mess. Could be related to screaming and running when enemy is close?

13. When the enemy is idling it searches for a unit to move to (basic attack logic?), if there is none it searches for a magic item and generates event 71 (aaah! That's how 71 is generated)

When non-idling:
Fanatics handling (event 78).
When it found a target it can shoot magic (items) through event 66.
Also permanently rescans for closer enemies and magic items. I guess attacking works over event 3. Event 3 invokes #43 which has branching for Steam tank (event 85) and everything else (event 7). Meh check this later again, because this gets worse...

So to want a completely stupid unit: Get rid of #3e.

Terminology for the next text: There are basicly two different types of "targets".
The Player can specify a target by clicking on the banner. The target is overwritten when in Close combat (CC) with somebody.
The other target is the 14h-target. Which is for the Player only populated when a regiment starts following a retreating regiment.

The enemy uses the 14h-target more: E.g. when moving to an enemy, 14h-target is set to this (havn't checked if target is also populated but would make sense - but at least in CC it is)

So will use 14h-target and target for the remaining text:

-----
Usages of #14 in B1_01:
Code:
on_event 19
#14 8, 4
end_event 6844
Sends event 4 to the caller (event source is sender of last event) when:
 - the sender of last event has a target
 - a distance check between caller and sender passes
 - caller has no target.

Note: Event 4 is:
Code:
on_event 4
#44 ; test can fight
set_return_func_iftrue 127
end_event 6844

Code:
on_event 20
#14 8, 4
end_event 6844

Code:
on_event 21
#14 9, 4
end_event 6844
Sends event 4 to the caller (event source is sender of last event) when:
 - The sender of the last event has a 14h-target
 - caller has a target
 - a distance check between 14h-target of sender and caller passes  

Code:
on_event 5
#14 5, -1
iftrue
send_event_to_stored_unit 21
endif
end_event 6844

Looks like this checks if the sender is a better candidate (distance-wise) then the 14h-target and sets 14h-target to sender if this is the case (sets TRUE)

send_event_to_stored_unit: E.g. for spawned zombies the stored unit is the wizard who spawned them. Field could have more purposes.

The event arg of #14 is ignored.

Code:
on_event 14
#14 18, -1
end_event 6844

When sender matches 14h-target the 14h-target is cleared.
When sender matches "stored unit" (see above) the "stored unit" is cleared.

When sender matches the target, then:
 - Makes no sense to me Smiley
 - Unsure: sourceless event 25 is sent to the caller when not in CC I think.
 - Sound effect 31 is played

event arg of #14 is ignored. Hardcoded to 25 (srsly).

Code:
on_event 22
#14 17, -1
end_event 6844

Same as 18, see above

Code:
on_event 11
#14 7, -1
end_event 6844

Also too chaotic for me.
One part of this is generating enemy sighted events.

The one who encountered something gets event 28 (source is the enemy who was sighted)
The one who was sighted gets event 29 (source is the one who saw him)

Event arg of #14 is ignored.

Code:
on_event 65
test_event_from_target
iftrue
test_unit_flag2 4
iftrue
play_self 22
endif
test_unit_flag1 512
iftrue
#14 17, -1
else
send_event_to_self 25
endif
endif
end_event 6844

17 was already explained above.

Code:
.func 106
reset_call_stack
#14 4, -1
wait_unit_flag1_clear 16392
play_self 1
#48
sleep
#4f
do
for 2
set_timer 10
#58
goto_iftrue 129
wait_for_timer
test_unit_flag1 16
iftrue
restore_ip
endif
next
#49
always

This sends event 5 to the current target. source is the caller.

The event of #14 is ignored, hardcoded to 5 (srsly).

Code:
.func 107
    reset_call_stack
    charge
    play_self 2
    #14 19, -1
    do
        sleep
        #b0 0
        test_unit_flag1 16
    whilenot
    goto 134

No idea. Result depends on the race. Does not generate events.

Code:
.func 116
    #62
    #50
    play_self 3
    #14 1, -1
    #4a
    send_event_to_self_iftrue 3
    sleep_iftrue
    clear_unit_flag1 17842328
    clear_unit_flag2 16
    goto 110

Called when a regiment starts retreating. The one following it sets the 14h-target to the one it follows.

No event generated.

Code:
.func 127
    #14 4, -1
    send_event_to_stored_unit 20
    wait_unit_flag1_clear 16392
    play_self 1
    #48
    #4f
    do
        for 2
            set_timer 10
            #58
            goto_iftrue 129
            wait_for_timer
            test_unit_flag1 16
            iftrue
                restore_ip
            endif
        next
        #49
    always

Already explained.

Code:
.func 130
    #14 6, -1
    block_movement
    do
        sleep
        #c6
    while
    do
        set_timer 20
        wait_for_timer
    always

Code:
.func 140
    set_event_handler 141
    #3c 64, 0
    do
        set_timer 10
        wait_for_timer
        #14 16, -1
    always

No idea.

Code:
.func 141
    clear_ctrl_flag 8
    do
        get_event
            on_event 52
                #14 15, -1
                end_event 6844
            @0xABC
        test_more_events
    while
    return_from_event_handler

Seems to be related to random movement. Adds a random number to the direction.

More possibilities for #14 not in the CTL:

2: Searches for a regiment using the normal find_regiment function (distance 100).

Sends event 4 (#14 evt arg ignored, yeah!) to the caller (source is the found regiment)

10: Standard handler for friends. Explained at the top.

11: No idea.

12: Standard handler for Peasants

13: Standard handler for AI

---

Objective L (12): The unit with this unit id will never get a white flag. Bernhardt has this on the Black Pyramide map.

---

I have a (quite incorrect) list of unit flags if you are interested.

Maybe is also worth to update ctldis so that it dissasembles unit flags into something more readable (or at least in hex so you don't need a calc to convert them Wink)
Pages: [1] 2 3 ... 65