Jump to content

Functional WEIDU


DavidW

Recommended Posts

About six months ago (partly motivated by having got my head vaguely around the principles of functional programming) I started playing around with a new way of coding in WEIDU, making very extensive use of functions. The basic idea is that (i) pretty much any interaction you have with a file type should be through calling some function; (ii) pretty much any automatic task you do (including building other functions) should also be done via a function; (iii) actual interaction with the underlying raw data (offsets, IDS codes etc) should be pushed as far as possible from the code.

 

The virtues (hopefully) are (i) shorter and more readable code; (ii) less buggy code; (iii) code that's much easier to adjust at a bulk level. (In some sense the design goals are a bit like for SSL, my BAF scripting metalanguage.) At the moment I'm particularly motivated by the desire to write code that can be very swiftly adjusted to BG:EE and BG2:EE.

 

I thought I'd mention it to see if there's any interest in me making it more generally accessible. I haven't got formal documentation, so in lieu, I'll give a few examples. (In each case, obviously, there's a big bunch of functions to load, but you do that once-and-for-all in the ALWAYS block at the start of your TP2 file.)

 

EDIT: basic and incomplete documentation below; current version attached (use at own risk!)

sfo.zip

Link to comment

Installing a bunch of files

 

Normal WEIDU:

ACTION_FOR_EACH file IN dw#cat1.cre dw#cat2.cre dw#cat3.cre dw#dog1.cre dw#dog2.cre dw#dog.itm dw#cat.itm BEGIN
    COPY ~scs/animals/%file%~ ~override~
END
ACTION_FOR_EACH script IN dw#cat.baf dw#dog.baf BEGIN
    COMPILE_EVALUATE_BUFFER ~%script%~
END

 

Functional WEIDU:

OUTER_SPRINT component_loc animals // usually done at start of component
LAF install STR_VAR files=~dw#cat1.cre dw#cat2.cre dw#cat3.cre dw#dog1.cre dw#dog2.cre dw#dog.itm dw#cat.itm dw#cat.baf dw#dog.baf~ END

Link to comment

Changing some features of a creature (class, level, etc)

 

Normal WEIDU:

COPY_EXISTING ~MOOK02.CRE~ ~override~							   // Mook (hostile)
 REMOVE_CRE_ITEM ~rndtre01~										// removes the random treasure 01 item
 REPLACE_CRE_ITEM ~LEAT01~ #0 #0 #0 ~UNSTEALABLE~ ~ARMOR~		  // unstealable Leather Armor (non-magical)
 REPLACE_CRE_ITEM ~SW1H04~ #0 #0 #0 ~UNSTEALABLE~ ~WEAPON1~		// unstealable Long Sword (non-magical)
 ADD_CRE_ITEM ~BOW04~ #0 #0 #0 ~UNSTEALABLE~ ~WEAPON2~ EQUIP TWOHANDED // Long Bow +1
 ADD_CRE_ITEM ~AROW01~ #20 #0 #0 ~UNSTEALABLE~ ~QUIVER3~		   // Arrows (non-magical)
 ADD_CRE_ITEM ~AROW02~ #20 #0 #0 ~UNSTEALABLE~ ~QUIVER2~		   // Arrows +1
 ADD_CRE_ITEM ~AROW05~ #20 #0 #0 ~UNSTEALABLE~ ~QUIVER1~		   // Arrows of Biting
 ADD_CRE_ITEM ~POTN10~ #2 #0 #0 ~UNSTEALABLE~ ~QITEM1~			 // Gives Mook 2x Potion of Invisibility
 ADD_CRE_ITEM ~POTN52~ #2 #0 #0 ~UNSTEALABLE~ ~QITEM2~			 // Gives Mook 2x Potion of Extra Healing
 WRITE_LONG 0x14 2500											  // XP value (when killed)
 WRITE_LONG 0x18 161000											// current XP
 WRITE_ASCII 0x34 ~RR#MOOKS~ #8									// Sets Mook's small portrait
 WRITE_BYTE 0x45 75												// Hide in Shadows skill
 WRITE_BYTE 0x54 10												// save vs. death
 WRITE_BYTE 0x55 12												// save vs. wands
 WRITE_BYTE 0x56 11												// save vs. polymorph
 WRITE_BYTE 0x57 12												// save vs. breath
 WRITE_BYTE 0x58 13												// save vs. spells
 WRITE_BYTE 0x64 50												// Detect Illusions skill
 WRITE_BYTE 0x67  0												// Open Locks skill
 WRITE_BYTE 0x68 55												// Move Silently skill
 WRITE_BYTE 0x69 10												// Find Traps skill
 WRITE_BYTE 0x6a 25												// Pick Pockets skill
 WRITE_BYTE 0x6f 0												 // BG1 Proficiency slot (small sword)
 WRITE_BYTE 0x75 0												 // BG1 Proficiency slot (missile)
 WRITE_BYTE 0x234 7												// level (first class)
 WRITE_BYTE 0x235 8												// level (second class)
 WRITE_BYTE 0x236 0												// level (third class)
 WRITE_BYTE 0x238 12											   // Strength
 WRITE_BYTE 0x23f 15											   // morale
 WRITE_BYTE 0x273 9												// class
 WRITE_ASCII 0x248 ~RR#MOOK~ #8									// assign override AI script
 WRITE_ASCII 0x250 ~None~ #8									   // disable class AI script (SHOUTDLG.BCS)
 WRITE_ASCII 0x258 ~None~ #8									   // disable race AI script (NONE)
 WRITE_ASCII 0x260 ~None~ #8									   // disable general AI script (NONE)
 WRITE_ASCII 0x268 ~None~ #8									   // disable default AI script (WTASIGHT.BCS)
 SET_BG2_PROFICIENCY ~PROFICIENCYLONGBOW~ 2						// Give Mook 2 stars in the BG2 Longbow proficiency
 SET_BG2_PROFICIENCY ~PROFICIENCYLONGSWORD~ 2					  // Give Mook 2 stars in the BG2 Longsword proficiency
BUT_ONLY_IF_IT_CHANGES

 

Functional WEIDU:

ACTION_CLEAR_ARRAY patch_data
ACTION_DEFINE_ASSOCIATIVE_ARRAY patch_data BEGIN
  remove_items => rndtre01
  add_items=>  ~leat01 sw1h04 bow04 arow01(20) arow02(20) arow05(20) potn10(2) potn52(2)~
  xp=>2500
  hide_in_shadows=>75
  detect_illusions=>50
  open_locks=>50
  move_silently=>55
  find_traps=>10
  pick_pockets=>0
  level=>7
  level2=>8
  wipe_bg1_proficiencies=>null
  strength=>12
  morale=>15
  class=>fighter_thief
  enforce_saves=>exact
  insert_script_high=>rr#mook
  strip_scripts=>~shoutdlg wtasight~
  set_proficiencies=>~longbow=>2 longsword=>2~
END

LAF edit_creature STR_VAR creature=rr#mook edits=patch_data END

Link to comment

Adding to an area script on a TUTU/BGT install

 

 

Normal WEIDU:

COPY_EXISTING ~%NWBaldursGate_House4_L2%.are~ ~override~
		 READ_ASCII 0x94 script
		 PATCH_IF ( ~%script%~ STRING_EQUAL ~~ || ~%script%~ STRING_EQUAL ~none~) BEGIN
				  SPRINT script ar0907
				  WRITE_ASCIIE 0x94 ~%script%~
		END
BUT_ONLY

ACTION_IF FILE_EXISTS_IN_GAME ~%script%.bcs~ BEGIN
 EXTEND_TOP ~%script%.bcs~ ~stratagems/assassin/scripts/ar0907_add.baf~ EVALUATE_BUFFER
END ELSE BEGIN
 COMPILE EVALUATE_BUFFER ~stratagems/assassin/scripts/ar0907_add.baf~
 COPY ~ar0907_add.bcs~ ~override/%script%.bcs~
END

 

Functional WEIDU:

 

OUTER_SPRINT component_loc assassin  // usually done at start of component

LAF get_area_script STR_VAR area=EVALUATE_BUFFER ~%NWBaldursGate_House4_L2%~ RET file=script END
LAF extend_script STR_VAR file top=ar0907_add location=scripts END

Link to comment

Editing every spell in the game so that if it gives immunity to Web it also gives immunity to dw#0w215.spl under the same conditions

 

Normal WEIDU:

 

 COPY_EXISTING REGEXP GLOB ~.*\.spl~ ~override~
 GET_OFFSET_ARRAY ab_array 0x64 4 0x68 2 0 0 0x28
 SET num_fx_added=0
 READ_LONG 0x68 fx_off_base
 PHP_EACH ab_array AS int =>ab_off BEGIN
   READ_SHORT ab_off+0x1e fx_ind
      READ_SHORT ab_off+0x20 fx_num
      SET fx_ind=fx_ind+num_fx_added
      WRITE_SHORT ab_off+0x1e fx_ind
      SET num_fx_added_here=0
      FOR (i=0;i<fx_num;i+=1) BEGIN
            PATCH_IF SHORT_AT (fx_off_base + (fx_ind + i + num_fx_added_here) * 0x30) = 206 BEGIN
                       READ_ASCII (fx_off_base + (fx_ind + i + num_fx_added_here) * 0x30 + 0x14) immune_old
                       PATCH_IF ~%immune_old%~ STRING_EQUAL_CASE SPWI215 BEGIN
                                   READ_ASCII (fx_off_base + (fx_ind + i + num_fx_added_here) * 0x30) template (0x30)
                                   SET num_fx_added_here +=1
                                   INSERT_BYTES (fx_off_base + (fx_ind + i + num_fx_added_here) * 0x30) 0x30
                                   WRITE_ASCIIE (fx_off_base + (fx_ind + i + num_fx_added_here) * 0x30) ~%template%~
                                   WRITE_ASCII (fx_off_base + (fx_ind + i + num_fx_added_here) * 0x30 + 0x14) dw#0w215
                       END
              END
       END
       SET fx_num += num_fx_added_here
       WRITE_SHORT ab_off+0x20 fx_num
       SET num_fx_added += num_fx_added_here
END
BUT_ONLY

 

Functional WEIDU:

 

ACTION_CLEAR_ARRAY patch_data
ACTION_DEFINE_ASSOCIATIVE_ARRAY patch_data BEGIN
   type=>effect
   match=>combine_checks
   match_parameter=>~opcode=>206 resource=>%WIZARD_WEB%~
   check=>1
   resource=>dw#0w215
END

LAF edit_all_spells STR_VAR editstring=~clone_entry=>patch_data~ END

Link to comment

Making a CRE file from scratch (this builds a 5th level Red Wizard)

ACTION_CLEAR_ARRAY patch_data
ACTION_DEFINE_ASSOCIATIVE_ARRAY patch_data BEGIN
	 class=>mage
	 race=>human
	 gender=>male
	 kit=>invoker
	 allegiance=>neutral
	 alignment=>lawful_evil
	 level=>5
	 strength=>10
	 intelligence=>17
	 wisdom=>9
	 dexterity=>14
	 constitution=>16
	 charisma=>12
	 set_proficiencies=>~dart=>1 staff=>1~
	 add_items=>~clck02 clck14 staf01 dart01(10) potn52(2)~
	 add_spells=>~MAGIC_MISSILE(3) SHIELD WIZARD_CHROMATIC_ORB MIRROR_IMAGE INVISIBILITY HORROR FIREBALL DISPEL_MAGIC WIZARD_LIGHTNING_BOLT~
	 script_override=>shout
	 script_class=>mage4
	 steal_colors_from=>edwin11
	 steal_sounds_from=>sewyag04
END



LAF make_creature STR_VAR creature=dw#redwz edits=patch_data END

 

 

(I could add enforce_mage=>null to do the spells and script automatically, but that's really part of SCS proper, not this functional package.)

Link to comment

Wow, eerie. I had just finished writing a series of functions to abstract area patch functions that I was going to submit for inclusion in the WeiDU function library. I.e.

 

COPY_EXISTING ~ar6002.are~ ~override~
 LPF cd_area_alter_cre INT_VAR x_coord = 2194 y_coord = 1264 STR_VAR cre_name = "Neo Orog 8" END
 LPF cd_area_alter_cre STR_VAR dlg_file = "dgenmond" cre_name = "Phase Spider" END
 LPF cd_area_alter_doors INT_VAR door_icon = 8 STR_VAR door_name = "AR6002PuzzleDoorTrigger" END
 BUT_ONLY

 

Feel free to borrow and modify if it furthers your master plan:

 

 

DEFINE_PATCH_FUNCTION cd_area_alter_entrance
 INT_VAR x_coord = "-1" // negative values not written
	  y_coord = "-1" // negative values not written
	  orient  = "-1" // negative values not written
 STR_VAR entry_name = ""
BEGIN

 READ_LONG  0x68 ent_off
 READ_LONG  0x6c ent_num
 FOR (index = 0 ; index < ent_num ; ++index) BEGIN
READ_ASCII (ent_off +		(index * 0x68)) "ent_name" (32) NULL
PATCH_IF ("%ent_name%" STRING_COMPARE_REGEXP  "%entry_name%" = 0) BEGIN
  PATCH_IF ("%x_coord%" >= 0) BEGIN WRITE_SHORT (ent_off + 0x20 + (index * 0x68)) "%x_coord%" END
  PATCH_IF ("%y_coord%" >= 0) BEGIN WRITE_SHORT (ent_off + 0x22 + (index * 0x68)) "%y_coord%" END
  PATCH_IF ("%orient%" >= 0)  BEGIN WRITE_LONG  (ent_off + 0x24 + (index * 0x68)) "%orient%" END
END
 END

END

DEFINE_PATCH_FUNCTION cd_area_alter_triggers
 INT_VAR type		= "-1"
	  cursor	  = "-1"
	  trap_detect = "-1"
	  trap_remove = "-1"
	  trapped	 = "-1"
	  detected	= "-1"
	  flag_locked		   = "-1"
	  flag_resets		   = "-1"
	  flag_party_required   = "-1"
	  flag_trap_detectable  = "-1"
	  flag_trap_enemies	 = "-1"
	  flag_tutorial		 = "-1"
	  flag_trap_npcs		= "-1"
	  flag_silent		   = "-1"
	  flag_deactivated	  = "-1"
	  flag_impassable_npc   = "-1"
	  flag_activation_point = "-1"
	  flag_connect_to_door  = "-1"
 STR_VAR trig_name   = ""
	  dest_area   = "same"
	  ent_name	= "same"
	  door_key	= "same"
	  door_script = "same"
BEGIN

 READ_SHORT 0x5a trig_num
 READ_LONG  0x5c trig_off
 FOR (index = 0 ; index < trig_num ; ++index) BEGIN
READ_ASCII (trig_off +		(index * 0xc4)) "trig_name_file" (32) NULL
PATCH_IF ("%trig_name%" STRING_COMPARE_REGEXP  "%trig_name_file%" = 0) BEGIN
  PATCH_IF ("%type%" >= 0)		BEGIN WRITE_SHORT (trig_off + 0x20 + (index * 0xc4)) "%type%"		END
  PATCH_IF ("%cursor%" >= 0)	  BEGIN WRITE_LONG  (trig_off + 0x34 + (index * 0xc4)) "%cursor%"	  END
  PATCH_IF ("%trap_detect%" >= 0) BEGIN WRITE_SHORT (trig_off + 0x68 + (index * 0xc4)) "%trap_detect%" END
  PATCH_IF ("%trap_remove%" >= 0) BEGIN WRITE_SHORT (trig_off + 0x6a + (index * 0xc4)) "%trap_remove%" END
  PATCH_IF ("%trapped%" >= 0)	 BEGIN WRITE_SHORT (trig_off + 0x6a + (index * 0xc4)) "%trapped%"	 END
  PATCH_IF ("%detected%" >= 0)	BEGIN WRITE_SHORT (trig_off + 0x6c + (index * 0xc4)) "%detected%"	END
  PATCH_IF ("%flag_locked%" = 0)		   BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11111110) END
  PATCH_IF ("%flag_resets%" = 0)		   BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11111101) END
  PATCH_IF ("%flag_party_required%" = 0)   BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11111011) END
  PATCH_IF ("%flag_trap_detectable%" = 0)  BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11110111) END
  PATCH_IF ("%flag_trap_enemies%" = 0)	 BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11101111) END
  PATCH_IF ("%flag_tutorial%" = 0)		 BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11011111) END
  PATCH_IF ("%flag_trap_npcs%" = 0)		BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b10111111) END
  PATCH_IF ("%flag_silent%" = 0)		   BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b01111111) END
  PATCH_IF ("%flag_deactivated%" = 0)	  BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BAND 0b11111110) END
  PATCH_IF ("%flag_impassable_npc%" = 0)   BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BAND 0b11111101) END
  PATCH_IF ("%flag_activation_point%" = 0) BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BAND 0b11111011) END
  PATCH_IF ("%flag_connect_to_door%" = 0)  BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BAND 0b11110111) END
  PATCH_IF ("%flag_locked%" = 1)		   BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT0) END
  PATCH_IF ("%flag_resets%" = 1)		   BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT1) END
  PATCH_IF ("%flag_party_required%" = 1)   BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT2) END
  PATCH_IF ("%flag_trap_detectable%" = 1)  BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT3) END
  PATCH_IF ("%flag_trap_enemies%" = 1)	 BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT4) END
  PATCH_IF ("%flag_tutorial%" = 1)		 BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT5) END
  PATCH_IF ("%flag_trap_npcs%" = 1)		BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT6) END
  PATCH_IF ("%flag_silent%" = 1)		   BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT7) END
  PATCH_IF ("%flag_deactivated%" = 1)	  BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BOR BIT0) END
  PATCH_IF ("%flag_impassable_npc%" = 1)   BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BOR BIT1) END
  PATCH_IF ("%flag_activation_point%" = 1) BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BOR BIT2) END
  PATCH_IF ("%flag_connect_to_door%" = 1)  BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BOR BIT3) END
  PATCH_IF ("%dest_area%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (trig_off + 0x38 + (index * 0xc4)) "%dest_area%" #8 // value from str_var
  END
  PATCH_IF ("%ent_name%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (trig_off + 0x40 + (index * 0xc4)) "%ent_name%" #32 // value from str_var
  END
  PATCH_IF ("%door_key%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (trig_off + 0x74 + (index * 0xc4)) "%door_key%" #8 // value from str_var
  END
  PATCH_IF ("%door_script%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (trig_off + 0x7c + (index * 0xc4)) "%door_script%" #8 // value from str_var
  END
END
 END

END

DEFINE_PATCH_FUNCTION cd_area_alter_cre
 INT_VAR x_coord = "-1"
	  y_coord = "-1"
	  orient  = "-1"
 STR_VAR cre_name		 = ""
	  dlg_file		 = "same"
	  script_override  = "same"
	  script_general   = "same"
	  script_class	 = "same"
	  script_race	  = "same"
	  script_default   = "same"
	  script_specifics = "same"
	  cre_file		 = "same"
BEGIN

 READ_LONG  0x54 cre_off
 READ_SHORT 0x58 cre_num
 FOR (index = 0 ; index < cre_num ; ++index) BEGIN
READ_ASCII (cre_off +		(index * 0x110)) cre_name_file (32) NULL
PATCH_IF ("%cre_name%" STRING_COMPARE_CASE "%cre_name_file%" = 0) BEGIN
  PATCH_IF ("%x_coord%" >= 0) BEGIN WRITE_SHORT (cre_off + 0x20 + (index * 0x110)) "%x_coord%"
									WRITE_SHORT (cre_off + 0x24 + (index * 0x110)) "%x_coord%" END
  PATCH_IF ("%y_coord%" >= 0) BEGIN WRITE_SHORT (cre_off + 0x22 + (index * 0x110)) "%y_coord%"
									WRITE_SHORT (cre_off + 0x26 + (index * 0x110)) "%y_coord%" END
  PATCH_IF ("%orient%" >= 0)  BEGIN WRITE_SHORT (cre_off + 0x34 + (index * 0x110)) "%orient%" END
  PATCH_IF ("%dlg_file%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (cre_off + 0x48 + (index * 0x110)) "%dlg_file%" #8 // value from str_var
  END
  PATCH_IF ("%script_override%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (cre_off + 0x50 + (index * 0x110)) "%script_override%" #8 // value from str_var
  END
  PATCH_IF ("%script_general%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (cre_off + 0x58 + (index * 0x110)) "%script_general%" #8 // value from str_var
  END
  PATCH_IF ("%script_race%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (cre_off + 0x68 + (index * 0x110)) "%script_race%" #8 // value from str_var
  END
  PATCH_IF ("%script_default%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (cre_off + 0x70 + (index * 0x110)) "%script_default%" #8 // value from str_var
  END
  PATCH_IF ("%script_class%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (cre_off + 0x60 + (index * 0x110)) "%script_class%" #8 // value from str_var
  END
  PATCH_IF ("%script_specifics%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (cre_off + 0x78 + (index * 0x110)) "%script_specifics%" #8 // value from str_var
  END
  PATCH_IF ("%cre_file%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (cre_off + 0x80 + (index * 0x110)) "%cre_file%" #8 // value from str_var
  END
END
 END

END

DEFINE_PATCH_FUNCTION cd_area_alter_container_trap
 INT_VAR trapped  = "-1"
	  detected = "-1"
 STR_VAR trap_script = "same"
	  cont_name   = ""
BEGIN

 READ_LONG  0x70 cont_off
 READ_SHORT 0x74 cont_num
 FOR (index = 0 ; index < cont_num ; ++index) BEGIN
READ_ASCII (cont_off +		(index * 0xc0)) cont_name_file (32) NULL
PATCH_IF ("%cont_name%" STRING_COMPARE_CASE "%cont_name_file%" = 0) BEGIN
  PATCH_IF ("%trapped%" >= 0) BEGIN WRITE_SHORT (cont_off + 0x30 + (index * 0xc0)) "%trapped%" END // value from int_var
  PATCH_IF ("%detected%" >= 0) BEGIN WRITE_SHORT (cont_off + 0x32 + (index * 0xc0)) "%detected%" END // value from int_var
  PATCH_IF ("%trap_script%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
	WRITE_ASCIIE (cont_off + 0x48 + (index * 0xc0)) "%trap_script%" #8 // value from str_var
  END
END
 END

END

DEFINE_PATCH_FUNCTION cd_container_icons
 INT_VAR cont_icon = 7
 STR_VAR cont_name = ""
BEGIN

 READ_LONG  0x70 cont_off
 READ_SHORT 0x74 cont_num
 FOR (index = 0 ; index < cont_num ; ++index) BEGIN
READ_ASCII (cont_off +		(index * 0xc0)) cont_name_file (32) NULL
PATCH_IF ("%cont_name%" STRING_COMPARE_CASE "%cont_name_file%" = 0) BEGIN
  WRITE_SHORT (cont_off + 0x24 + (index * 0xc0)) "%cont_icon%" // update icon if matched
END
 END

END

DEFINE_PATCH_FUNCTION cd_area_alter_doors
 INT_VAR door_icon   = "-1"
	  trap_detect = "-1"
	  trap_remove = "-1"
	  trapped	 = "-1"
	  detected	= "-1"
	  door_detect = "-1"
	  lock_diff   = "-1"
 STR_VAR door_name   = ""
	  door_key	= "same"
	  door_script = "same"
BEGIN

 READ_LONG 0xa4 door_num
 READ_LONG 0xa8 door_off
 FOR (index = 0 ; index < door_num ; ++index) BEGIN
READ_ASCII (door_off +		(index * 0xc8)) door_name_file (32) NULL
PATCH_IF ("%door_name%" STRING_COMPARE_CASE "%door_name_file%" = 0) BEGIN
  PATCH_IF ("%door_icon%" >= 0)   BEGIN WRITE_LONG  (door_off + 0x68 + (index * 0xc8)) "%door_icon%"   END
  PATCH_IF ("%trap_detect%" >= 0) BEGIN WRITE_SHORT (door_off + 0x6c + (index * 0xc8)) "%trap_detect%" END
  PATCH_IF ("%trap_remove%" >= 0) BEGIN WRITE_SHORT (door_off + 0x6e + (index * 0xc8)) "%trap_remove%" END
  PATCH_IF ("%trapped%" >= 0)	 BEGIN WRITE_SHORT (door_off + 0x70 + (index * 0xc8)) "%trapped%"	 END
  PATCH_IF ("%detected%" >= 0)	BEGIN WRITE_SHORT (door_off + 0x72 + (index * 0xc8)) "%detected%"	END
  PATCH_IF ("%door_detect%" >= 0) BEGIN WRITE_LONG  (door_off + 0x88 + (index * 0xc8)) "%door_detect%" END
  PATCH_IF ("%lock_diff%" >= 0)   BEGIN WRITE_LONG  (door_off + 0x8c + (index * 0xc8)) "%lock_diff%"   END
  PATCH_IF ("%door_key%" STRING_COMPARE_CASE "same") BEGIN // if key not set to same
	WRITE_ASCIIE (door_off + 0x78 + (index * 0xc8)) "%door_key%" #8 // value from str_var
  END
  PATCH_IF ("%door_script%" STRING_COMPARE_CASE "same") BEGIN // if key not set to same
	WRITE_ASCIIE (door_off + 0x80 + (index * 0xc8)) "%door_script%" #8 // value from str_var
  END
END
 END

END

 

Link to comment

Actually, the idea of the functional framework is more that functions like these can be quickly written on the fly. Here's my way of doing the edit you're doing above (sorry for the bad visual formatting, I've never really got the hang of doing it in BBcode):

 

ACTION_CLEAR_ARRAY patch_data
ACTION_DEFINE_ASSOCIATIVE_ARRAY patch_data BEGIN
  patch_cond_inline=>~type=>actor match=>actor_name  check=>"neo orog 8" actor_x_coord_start=>2194 actor_y_coord_start=>1264 creature_name=>"neo orog 8"~
 patch_cond_inline'=>~type=>actor match=>actor_name check=>"Phase Spider" dialog=>dgenmond~
 patch_cond_inline''=>~type=>door match=>door_name check=>AR6002_Puzzle_Door_Trigger door_icon=>8~
END

LAF edit_area STR_VAR area=ar6002 edits=patch_data END

 

There's an early version of the code in the fixpack part of IWD-in-BG2 v7, if you're interested.

 

(By the way, can I infer from the particular example you're doing that you're returning to IWD-in-BG2?)

Link to comment

As long as we can stil variablize the source and target, I think this is pretty darned cool -

 

LAF get_area_script STR_VAR area=EVALUATE_BUFFER ~%NWBaldursGate_House4_L2%~ RET file=script END

made me very happy indeed.

 

and I say the easier it is to set this up the better. You want to grab Mike1072 if you can, too, as he has a set of macros that might be very cool to integrate.

Link to comment

Don't waste you time on trying to make it user-friendly. By doing so you risk switching your priorities from actually modding to writing code that none will use in the end.

 

The only stuff that really needs to be included in WeiDU are the most basic/universal macros/functions, by adding things like Cam's ones the only real achievement you may hope for is the size increase of the executable, 1-2 people who will use them don't count. Anything specific should be kept to the mod's lib.

 

 

PS To clarify, my point is that you can never prepare for everything, so the best course of action within such a small community as ours is to concentrate on your own needs. We don't aim to save the humanity, we can only either to make mods for a small number of players or to write code for a tiny number of modders - and you can bet their needs will differs from yours.

Link to comment

As long as we can stil variablize the source and target, I think this is pretty darned cool

 

Do you mean use different source and target? If so, yes:

LAF clone_creature STR_VAR creature=~lich01=>dw#lich~ edits=patch_data END

 

Or do you mean use a variable as creature name? If so, again yes: these are just WEIDU functions.

Link to comment

Actually, the idea of the functional framework is more that functions like these can be quickly written on the fly. Here's my way of doing the edit you're doing above (sorry for the bad visual formatting, I've never really got the hang of doing it in BBcode):

Got it. I think I somewhat agree with Ardanis--I suspect the people who could use something like this are more or less the same folks who are already more than comfortable with loops, arrays, functions, and many of the other advanced WeiDU goodies this could supplant.

 

There's an early version of the code in the fixpack part of IWD-in-BG2 v7, if you're interested.

 

(By the way, can I infer from the particular example you're doing that you're returning to IWD-in-BG2?)

I knew you wouldn't miss the implications of what I had posted. :) Let's just say I'm finally looking through some of devSin's old zip files.

Link to comment

Actually, the idea of the functional framework is more that functions like these can be quickly written on the fly. Here's my way of doing the edit you're doing above (sorry for the bad visual formatting, I've never really got the hang of doing it in BBcode):

Got it. I think I somewhat agree with Ardanis--I suspect the people who could use something like this are more or less the same folks who are already more than comfortable with loops, arrays, functions, and many of the other advanced WeiDU goodies this could supplant.

 

That's my guess too. It's not really intended to make things easier for novices, more as a power tool for people who already know what they're doing. (There came a point where I realised that if I never hand-coded another loop through offsets again, it would be too soon.)

Link to comment
That's my guess too. It's not really intended to make things easier for novices...
Well, what wouldmake it easier for ... well me, is to have all the extensivelly commented original functions at some place, these:
Normal WEIDU:
plah

Link to comment
That's my guess too. It's not really intended to make things easier for novices...
Well, what wouldmake it easier for ... well me, is to have all the extensivelly commented original functions at some place

 

Would you also like a pony?

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...