Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 23 24 [25] 26 27 ... 42

Author Topic: [DFHack] Roses' Script Collection Updated 5/4/15  (Read 70882 times)

TheDorf

  • Bay Watcher
    • View Profile
Re: DFHack Spells (civilization scripts now uploaded)
« Reply #360 on: October 26, 2014, 07:00:16 am »

I have taken a short break on the finishing of the "event" scripts to work on a gui. What I have come up with, so far. is a way to view a unit, it's attributes, skills, syndromes, interactions, and classes.
Spoiler (click to show/hide)
There is more I want to add to the view, but I am happy with the way it is progressing. I will be finishing up the "event" scripts this week.



On a side note, is there anyone that is using the class/civilization scripts, or any of my other scripts? Don't feel bad if you aren't, I am mostly making these for my own use, in my, what seems like never, to be released mod. Just wondering if they are at all useful for the community.

I'm thinking of using the class script in my mod. I'm not entirely sure how it works though. Are skills and attributes still raised normally, while the class levels give access to interactions and/or spells? Also, does it work for npcs/world-gen? If not, that's not necessarily a big problem, seeing as I'm going to be making a rather "gamey" mod, so player vs npc progression doesn't need to be identical, but it's still nice to know how it works. :)

Does the civilization script work for NPC entities btw? Something that I think would be rather interesting is if they would allow different, branching "progression paths". If I could have like 3 different Gnoll entities that all progress in random directions, that would be awesome.
Pretty much something like this:
Reach 100,000 production value -> Path A
   Reach 200,000 production value -> Path AA
   Reach 10,000 exported wealth -> Path AB

Reach 10,000 exported wealth -> Path B
   Reach 100,000 production value -> Path BA
   Reach 20,000 exported wealth -> Path BB


Where path A* could allow the civilization to have pets, and B* could allow the civilization to use weapons, while *A could give them access to spells, and *B could give them access to armor.
So essentially:
AA would give pets and spells
AB would give pets and armor
BA would give weapons and spells
BB would give weapons and armor

Now, I'm not sure what the optimal way to set this up would be, but if you could somehow make it possible for progression to vary between games, that'd be awesome. On the other hand, I'm not sure if civilizations will ever create weapons/armor if they can't access it during world gen.
Logged
I love this community. Somebody asks "hay guise how do i tame shark", and then everybody is like "why don't we fling sharks at things with complex mechanical devices?".

Roses

  • Bay Watcher
    • View Profile
Re: DFHack Spells (civilization scripts now uploaded)
« Reply #361 on: October 26, 2014, 11:20:12 am »

For the class mod, skills and attributes are raised normally, but can also be raised when you level up a class. The majority of the purpose is for interactions though. It unfortunately does not work for NPCs or World Gen. I'm not sure if there is a way I could make it work, but I will think about it.

For the civilizations mod, it is currently only for NPC entities. Branching paths could be an interesting feature, I will see about adding them in. As for the creation of weapons/armor and the bringing of pets, I have been told that they work just like if they had had access to them during World Gen, although I have not tested them myself.

One thing I would like to do is to combine the civilization and class mods so that entities can gain access to different classes and different interactions as they level. The issue is how to go about assigning classes and syndromes to units that are not on the map.
Logged

TheDorf

  • Bay Watcher
    • View Profile
Re: DFHack Spells (civilization scripts now uploaded)
« Reply #362 on: October 26, 2014, 11:32:27 am »

For the class mod, skills and attributes are raised normally, but can also be raised when you level up a class. The majority of the purpose is for interactions though. It unfortunately does not work for NPCs or World Gen. I'm not sure if there is a way I could make it work, but I will think about it.
As I said, I'm probably gonna go for a "gamey" mod, so it's not gonna be a problem. However, classes for NPCs as well would be awesome. Would it be possible to include a boolean that, if true, causes the script to loop through all entries in legends mode and calculate class levels by checking the kills of all historical figures? Like this, historical figures could be somewhat "heroic", with spells, interactions and the like. I guess it could be a hassle to write, so if it's not something you'd personally like, you obviously shouldn't do it simply because I would like that feature.

For the civilizations mod, it is currently only for NPC entities. Branching paths could be an interesting feature, I will see about adding them in. As for the creation of weapons/armor and the bringing of pets, I have been told that they work just like if they had had access to them during World Gen, although I have not tested them myself.

One thing I would like to do is to combine the civilization and class mods so that entities can gain access to different classes and different interactions as they level. The issue is how to go about assigning classes and syndromes to units that are not on the map.

This all sounds awesome. Especially if you could somehow make classes work for NPCs as well. It's mostly for fortress mode though, right? I'd be truly amazed if it caused sites in adventure to have the pets, weapons, armors etc. that civilizations are given access to.
Logged
I love this community. Somebody asks "hay guise how do i tame shark", and then everybody is like "why don't we fling sharks at things with complex mechanical devices?".

palu

  • Bay Watcher
  • Viva la resolution
    • View Profile
Re: DFHack Spells (civilization scripts now uploaded)
« Reply #363 on: October 26, 2014, 07:52:35 pm »

I do have several examples, but currently the interaction-trigger isn't working for me, so I don't want to post any examples until I know they work. When that happens I will post all the examples I have.
No, i mean the raw text files. I'm not exactly sure what I shoild put there. What type of raw do they compile to?
Logged
Hmph, palu showing off that reading-the-instructions superpower.
The internet encourages thoughtful, intelligent discussion and if you disagree I hate you.
DFHack DF2015 progress:

Roses

  • Bay Watcher
    • View Profile
Re: [DFHack] Roses' Script Collection
« Reply #364 on: October 28, 2014, 11:58:39 am »

I figured it was about time to update the first post. Check it out for what is included in my scripts, what I am working on now, and what I have planned!
Logged

Roses

  • Bay Watcher
    • View Profile
Re: [DFHack] Roses' Script Collection
« Reply #365 on: October 29, 2014, 12:33:06 am »

Today we are going to talk about Classes

The Class System allows for a user defined upgrade structure for PC characters in Fortress mode. The key features are
  • Working experience system - Gain experience through killing, using interactions, and reactions
  • Class requirements - Restrict classes based on experience, attributes, traits, skills
  • Class bonuses - Gain attributes and skills based on class level
  • Class trees - Create complicated class trees by requiring other classes
As you can see it allows for lots of different customization! So let's get started. First off, let's go over what you will need.
  • Dwarf Fortress
  • DFHack
  • My Script Collection
  • Python v3+ (might work with 2.7, have not tried)
The files in my script collection that are related to the Class System
  • hack/lua/classes/establish-class.lua
  • hack/lua/classes/read-file.lua
  • hack/lua/classes/requirements-class.lua
  • hack/lua/classes/requirements-spell.lua
  • hack/scripts/classes/add-experience.lua
  • hack/scripts/classes/change-class.lua
  • hack/scripts/classes/learn-skill.lua
  • hack/scripts/base/classes.lua
  • hack/scripts/unit/attribute-change.lua
  • hack/scripts/unit/skill-change.lua
  • hack/scripts/unit/trait-change.lua
  • raw/objects/classes.txt
  • raw/objects/spells.txt
  • raw/classes_setup.py

So, where to start? For virtually everything you want to do, the only two files you will need to work with are the two .txt files, classes.txt and spells.txt. classes is where you will specify everything related to the classes, and spells is used to coordinate reactions/inorganics/syndromes and everything else needed for ease of use.

Let's look at classes.txt:

This text file will contain all of your defined classes, each following a specific format. The structure of the classes can be broken down into four separate parts, the base, bonuses, requirements, and spells
Code: [Select]
[CLASS:SQUIRE]
# Base tokens
[NAME:squire]       
[EXP:10:20]               
[LEVELS:2]
# Bonus tokens           
[BONUS_PHYS:STRENGTH:50:75:100]       
[BONUS_MENT:WILLPOWER:10:20:30]     
[BONUS_SKILL:AXE:1:2:2]                   
[BONUS_TRAIT:ANGER:-5:-5:-5]
# Requirement tokens
[REQUIREMENT_PHYS:STRENGTH:1500]       
[REQUIREMENT_MENT:WILLPOWER:1000]     
[REQUIREMENT_SKILL:AXE:4]                   
[REQUIREMENT_TRAIT:ANGER:45]
[REQUIREMENT_CLASS:PEASANT:1]
[REQUIREMENT_COUNTER:TRAIN:5]
[FORBIDDEN_CLASS:ACOLYTE:1]
# Spell tokens
[SPELL:SPELL_TEST_1:0]
 [SPELL_REQUIRE_PHYS:AGILITY:1500]
 [SPELL_REQUIRE_MENT:FOCUS:1500]
 [SPELL_FORBIDDEN_CLASS:ACOLYTE:0]
 [SPELL_FORBIDDEN_SPELL:SOME_OTHER_SPELL]
 [SPELL_COST:100]
 [SPELL_UPGRADE:SOME_OTHER_SPELL]
Those are all of the currently supported tokens for each class. You can have as many or as few of each that you want (e.g. you can require multiple physical attributes or none)

Now to looks at the tokens individually and see what each one does.
Base tokens
These tokens are the only mandatory tokens for a class
  • [NAME] specifies what the class is called in-game, and what name appears next to your dwarf (e.g. Squire Urist McDwarf)
  • [LEVELS] specifies how many different levels a class has
  • [EXP] specifies the required experience amount for each level, note that you need as many numbers here as you have levels
Bonus tokens
These tokens give your dwarf extra bonuses for being the class, and for each level, note that, unlike experience, you need to have 1 + the number of levels, where the first number signifies the bonus for level 0. You can have any number of these bonuses.
  • [BONUS_PHYS] - adds (or subtracts) a set amount from the units specified physical attribute, the amount is total, not cumulative, so a level 2 Squire has a total of +100 strength, not +225
  • [BONUS_MENT] - same as [BONUS_PHYS] except for the mental attributes
  • [BONUS_SKILL] - same as [BONUS_PHYS] except for the units skills
  • [BONUS_TRAIT] - same as [BONUS_PHYS] except for the units traits
Requirement tokens
These tokens place restrictions on the class and which Dwarfs can be the class. Unlike bonuses there is only one number needed, as bonuses are checked for becoming the class, not for each level.
  • [REQUIREMENT_PHYS] - this states that the unit must have a minimum amount of the specified physical attribute in order to become the class
  • [REQUIREMENT_MENT] - same as [REQUIREMENT_PHYS] except for mental attributes
  • [REQUIREMENT_SKILL] - same as [REQUIREMENT_PHYS] except for skills
  • [REQUIREMENT_TRAIT] - same as [REQUIREMENT_PHYS] except for traits
  • [REQUIREMENT_CLASS] - this states that the unit must have reached the specified level in the specified class
  • [REQUIREMENT_COUNTER] - this is to be used with my counters script, and so is outside of the scope of this tutorial
  • [FORBIDDEN_CLASS] - this works in conjunction with [REQUIREMENT_CLASS] except instead of needing the specified class at the specified level, it forbids a unit of class/level from being this class
Spell tokens
Here is where the classes get interesting. You can only learn specific spells (i.e. interactions) if you are a specific class. Each spell is defined in the same way, and comes with it's own set of special tokens
  • [SPELL] - this always starts off the defining of a spell and is the only mandatory token, the name is arbitrary, but must be unique, the number is the level at which the spell can be learned by the class. Instead of a number, 'AUTO' can be placed instead, this will mean that, as soon as the Dwarf becomes the class, it will learn those spells (as opposed to being taught through reactions)
  • [SPELL_REQUIRED_PHYS], [SPELL_REQUIRED_MENT], and [SPELL_FORBIDDEN_CLASS] - these work the same as the class versions, except dictate whether the unit can learn the spell
  • [SPELL_FORBIDDEN_SPELL] - this only lets a unit learn this spell if it hasn't learned the specified forbidden spell
  • [SPELL_COST] - this is an advanced tag that I will touch on later, by default the cost of learning all spells is set to 0
  • [SPELL_UPGRADE] - instead of learning a completly new spell, you will instead forget an old spell and learn this one in it's place (in game terms, you will lose the syndrome that gave you the previous spell, and gain the syndrome that gives you this spell, instead of keeping both)
Misc tokens
There is currently only one other token available besides the above mentioned, and that is the [AUTO_UPGRADE] token. Formatted like
Code: [Select]
[AUTO_UPGRADE:WARRIOR]this token tells the game that as soon as the max level of the class is reached, to change the units class to the WARRIOR class (e.g. when you reach SQUIRE level 2, change to WARRIOR level 0). This simplifies some of the micro-management of certain class trees.

So now you know how to set up your classes.txt file, note that there is no limit to the number of classes you can have, but each one must have a unique identifier (e.g. SQUIRE)

Now we will take a look at the spells.txt file, this file will help you set up everything you need in game, and, along with the python routine, automate several steps. This file is very basic
Code: [Select]
[SPELL:SPELL_TEST_1] <- simply label each [SPELL] as they are labeled in the classes.txt file
[CDI:INTERACTION:SPELL_FIRE_FIREBALL] <- and place any interaction information you would normally have here
[CDI:ADV_NAME:Fire Ball]
[CDI:TARGET:C:LINE_OF_SIGHT]
[CDI:TARGET_RANGE:C:15]
[CDI:USAGE_HINT:ATTACK]
[CDI:VERB:cast Fire Ball:casts Fire Ball:NA]
[CDI:TARGET_VERB:is caught in a ball of fire:is caught in a ball of fire]
[CDI:MAX_TARGET_NUMBER:C:1]
[CDI:WAIT_PERIOD:2000]
That's it!

Now we move to the python script. With classes.txt and spells.txt placed in your raw/objects/ folder and the python placed in the raw/ folder. Run the python script. If all goes well it will generate four text files;
  • dfhack_input.txt
    • Simply copy and paste the information from dfhack_input.txt into onLoad.init in your raws/objects folder
  • inorganic_dfhack_class.txt
    • Double check to make sure it looks correct, then simply move the file into your raws/objects folder
  • permitted_reactions.txt
    • Copy and paste this text into your desired entity
  • reaction_classes.txt
    • Here is where you have to do some extra work
    • If you have a CDI:ADV_NAME in spells.txt you will see it appear in the NAME of the reaction, otherwise you will see #YOUR_SPELL_NAME_HERE#, replace this with your desired spell name
    • In the BUILDING of the reaction, you will see #YOUR_BUILDING_HERE#, replace this with your desired building name
    • You will notice there are no skills, reagents, or products associated with these reactions. While none are necessary, you may wish to add material costs to changing classes or learning spells
    • Once you are happy with your changes, simply move the file into the raws/objects/ folder
And now you are all set to start using classes!

Addendum 1: Experience system
By default the game awards 1 experience point for each kill, whether it be a turtle or a dragon, to address this issue there are several avenues a modder can take.
  • Adding [CREATURE_CLASS:EXPERIENCE_X], where X is some positive integer, will instead mean that killing that creature rewards X amount of experience
  • In hack/scripts/base/classes.lua, at the top of the file, you will see radius = -1, this is the default behavior, and means that only the unit that struck the killing blow (in truth, only the unit listed as LAST_ATTACKER in DFHack when the target dies) will gain the experience. Increasing the number to above 0 means that any friendly unit within the radius of the unit who struck the killing blow will receive the experience.
  • Experience can be gained through reactions by placing
    modtools/reaction-trigger -reaction 'YOUR_REACTION_HERE' -command [ classes/add-experience -unit \\WORKER_ID -amount X ]
    into your onLoad.init, and every time you run the given reaction, you will gain X experience for your current class
  • Modders can also add experience gains to interaction usage (this allows for classes like healers, who will rarely kill anything, to still gain experience). This experience is not shared over nearby units if the radius is increased, but instead is just for the user of the interaction. To do this simply place;
    modtools/interaction-trigger -onAttackStr 'YOUR_CDI:VERB_HERE' -command [ classes/add-experience -unit \\ATTACKER_ID -amount X ]
    into your onLoad.init, and every usage of the interaction will award you with X experience for your current class
These options allow for earning experience to be smoother and more reliable.

Addendum 2: Spell costs
In addition to class and global experience, the system also tracks, what I call, skill experience. You can think of this as the "skill points". By default all spells cost 0 skill points to learn. Increasing this number means that a unit will spend these skill points to learn the spell. An example;

Unit becomes class Squire
Unit kills 20 experience worth of creatures
Unit now has 20 class experience, 20 global experience and 20 skill experience
Unit learns a spell that costs 10 skill points
Unit now has 20 class experience, 20 global experience, and 10 skill experience
Unit then changes to class Warrior
Unit kills 10 experience worth of creatures
Unit now has 10 class experience, 20 global experience, and 20 skill experience

In the future it may be possible to relate skill experience to levels gained, instead of experience gains, but for now, the system is set with experience.
Logged

Roses

  • Bay Watcher
    • View Profile
Re: [DFHack] Roses' Script Collection
« Reply #366 on: October 29, 2014, 09:58:59 am »

That should be a good starting place for those of you interested in the class system. If you have any comments/suggestions/questions just let me know. I will put a similar thing together for the civilization system.
Logged

Putnam

  • Bay Watcher
  • DAT WIZARD
    • View Profile
Re: [DFHack] Roses' Script Collection
« Reply #367 on: November 05, 2014, 03:26:55 pm »

...How exactly are spells learned? That information's not really in the guide...

Roses

  • Bay Watcher
    • View Profile
Re: [DFHack] Roses' Script Collection
« Reply #368 on: November 05, 2014, 03:39:47 pm »

Very good point, can't believe I overlooked that. All you need to do is use the command
Code: [Select]
classes/learn-spell -unit UNIT_ID -spell NAME_YOU_GAVE_SPELLWhere UNIT_ID is \\WORKER_ID or \\ATTACKER_ID or whatever method you are using to identify the id of the unit

So, for instance as a reaction
Code: [Select]
modtools/reaction-trigger -reactionName LEARN_BURN -command [ classes/learn-spell -unit \\WORKER_ID -spell BURN ]This will teach your unit burn, if they meet all the requirements.

I will update the post accordingly.
Logged

Putnam

  • Bay Watcher
  • DAT WIZARD
    • View Profile
Re: [DFHack] Roses' Script Collection
« Reply #369 on: November 05, 2014, 03:55:09 pm »

Any way to just have them automatically learn the spell as they level up?

Roses

  • Bay Watcher
    • View Profile
Re: [DFHack] Roses' Script Collection
« Reply #370 on: November 05, 2014, 07:17:21 pm »

Yep, if you put AUTO instead, but then they will learn them all at the first level. So with the current system you would have to have a bunch of classes with only 1 level, then have them learn the spell at the start of each new class. I will add a system for them to be learned automatically at each level appropriately.
Logged

expwnent

  • Bay Watcher
    • View Profile
Re: [DFHack] Roses' Script Collection
« Reply #371 on: November 07, 2014, 12:18:01 am »

So as I understand it, the problem with interaction-trigger is that it only detects when there is exactly one "attacker" and exactly one "defender" and they happen on the same tick and it can tell the units apart: they either have different names or are standing in different tiles or both.

I could handle multiple defenders relatively easily by just passing a list of defenders. Multiple attackers don't make sense of course because those should always be handled as separate events. Zero defenders is tricky because it won't be able to tell whether it just failed to find a defender or whether there are no defenders because it's a self-cast effect.

I could do a separate event for interactions where there are no targets. I'm tempted to do this because in terms of detection the two are very different and in terms of scripting they're different because you don't need to be passed a null pointer to the nonexistent defender. This seems like a slightly more "type-safe" solution. In general that's a good idea.

One major problem is detection. It's easy to get a list of units that are either the attacker or the defender. The tricky part is figuring out who is the attacker. I could require that the raw modder make the interaction label the attacker with a short-duration syndrome but I'd like to avoid that if possible. All I have is a list of units for whom the announcement was relevant, the location of the attack, the location of the defense, and the text of the announcement. From the text of the announcement it is usually obvious but not always if there are multiple invaders with the same name as used by combat reports: "the goblin lasher", for example. Still not a perfect solution.

What are the other problems with it? I forget. Were there problems with detecting regular old unit attacks / attacks with a particular type of sword? I do remember it doesn't distinguish between punching someone while holding a sword and actually hitting someone with the sword. It does require that you actually inflict some injury. Blocking/dodging/etc makes it not trigger.
Logged

Roses

  • Bay Watcher
    • View Profile
Re: [DFHack] Roses' Script Collection
« Reply #372 on: November 07, 2014, 11:56:19 am »

Yeah, I know detecting the attacker has always been the tricky part, I don't have any ideas though. The current way you are doing it seems to be the only way. I suppose forcing the modder to add a short-duration syndrome would make detection easier, but would be a rather clunky solution.

I never tried with regular attacks, only simple interactions. I could never get it working in arena, it just wouldn't say or do anything, both when individually controlled and when left to just run. It is completely possible that I just did something wrong though. Do you have an example that works in the arena?
Logged

expwnent

  • Bay Watcher
    • View Profile
Re: [DFHack] Roses' Script Collection
« Reply #373 on: November 07, 2014, 02:03:12 pm »

Code: [Select]
[CAN_DO_INTERACTION:INTERACTION_EXAMPLE1]
[CDI:ADV_NAME:Doom1]
[CDI:VERB:doom1:doom1s:doom1 each other]
[CDI:TARGET:A:LINE_OF_SIGHT]
[CDI:TARGET_RANGE:A:10]
[CDI:MAX_TARGET_NUMBER:A:1]
[CDI:WAIT_PERIOD:10]
[CAN_DO_INTERACTION:INTERACTION_EXAMPLE2]
[CDI:ADV_NAME:Doom2]
[CDI:VERB:doom2:doom2s:doom2 each other]
[CDI:TARGET:A:LINE_OF_SIGHT]
[CDI:TARGET_RANGE:A:10]
[CDI:MAX_TARGET_NUMBER:A:1]
[CDI:WAIT_PERIOD:10]

Code: [Select]
interaction_doom

[OBJECT:INTERACTION]

[INTERACTION:INTERACTION_EXAMPLE1]
 [I_SOURCE:CREATURE_ACTION]
 [I_TARGET:A:CREATURE]
  [IT_LOCATION:CONTEXT_CREATURE]
  [IT_MANUAL_INPUT:creature]
 [I_EFFECT:ADD_SYNDROME]
  [IE_TARGET:A]
  [IE_IMMEDIATE]
  [SYNDROME]
   [SYN_NAME:doom syndrome1]
   [CE_BLEEDING:SEV:100:PROB:100:START:0:END:10:BP:BY_CATEGORY:ALL:ALL]

[INTERACTION:INTERACTION_EXAMPLE2]
 [I_SOURCE:CREATURE_ACTION]
 [I_TARGET:A:CREATURE]
  [IT_LOCATION:CONTEXT_CREATURE]
  [IT_MANUAL_INPUT:creature]
 [I_EFFECT:ADD_SYNDROME]
  [IE_TARGET:A]
  [IE_IMMEDIATE]
  [SYNDROME]
   [SYN_NAME:doom syndrome2]
   [CE_BLEEDING:SEV:100:PROB:100:START:0:BP:BY_CATEGORY:ALL:ALL]


Code: [Select]
modtools/interaction-trigger -onAttackStr "doom2s" -command [ devel/print-args verb \\ATTACK_VERB defend_verb \\DEFEND_VERB attackerId \\ATTACKER_ID defenderId \\DEFENDER_ID attackReport \\ATTACK_REPORT defendReport \\DEFEND_REPORT ]

This seems to work for me.

Note that due to a change in DF internals, only the announcements actually visible to the user exist now. This limits things a bit. You have to make it so that the interactions at least initially appear in the combat logs, but you can suppress the announcements after detecting them.
Logged

Roses

  • Bay Watcher
    • View Profile
Re: [DFHack] Roses' Script Collection
« Reply #374 on: November 07, 2014, 02:23:34 pm »

I must have a previous version or something. Putting everything in their proper places and then running the arena I get Dwarf 1 doom2s! But nothing shows up.

I also tried putting the interaction-trigger line directly into the DFHack command line and got this
Code: [Select]
DFHack is ready. Have a nice day!
Type in '?' or 'help' for general help, 'ls' to see all commands.
[DFHack]# ENDER_ID attackReport \\ATTACK_REPORT defendReport \\DEFEND_REPORT ]
..\..\..\library\modules\EventManager.cpp:983: too few actors for report 1
reportStr = "Dwarf 1 doom1s!", pos = 95,93,4
[DFHack]# ENDER_ID attackReport \\ATTACK_REPORT defendReport \\DEFEND_REPORT ]
[DFHack]#
Logged
Pages: 1 ... 23 24 [25] 26 27 ... 42