Chaos Project

RPG Maker => RPG Maker Scripts => Script Requests => Topic started by: KCMike20 on January 04, 2009, 06:33:00 am

Title: [RESOLVED] Script Request: Threat/Aggro System [XP]
Post by: KCMike20 on January 04, 2009, 06:33:00 am
The Idea:

With the popularity of the MMORPG, I'm surprised this hasn't been done yet, but I'm sure quite a few people would be quick to include a system like this.  Would anyone be willing to take up scripting this?

In RPG Maker XP's default battle system, enemies seemingly target your characters randomly, although battlers in the front row have a higher chance of being targeted than those in the back.  What this script would do is create a threat/aggro system, where each action your battlers perform creates a certain amount of overall threat for his or herself.  This script stores a separate value for each actor that keeps track of the amount of threat they have generated, and enemy actors always target the party member with the highest threat when attacking (or if two actors have the same value, the target is randomly selected between the two).  This has the possibility of creating a more strategic battle system where the player has to balance using strong abilities which produce a high amount of threat with defensive maneuvers to keep the battlers alive.



Customization and Further Explanation:

Now, I'm no scripting genius, but I'd imagine the customization layout would look something along the lines of this:

Max_Threat = 100
When ID then return [[X, Y]]

when 1 then return [[0, 0]]
when 2 then return [[50, 0]]
when 3 then return [[-100, 0]]
when 4 then return [[30, -10]]

This script allows the user to determine the maximum threat possible as well as the amount of threat each skill produces or removes from the actor using it.  The ID is the ID Number of the skill in the database, the X value is the amount of threat a skill produces (or removes) for the actor using it and the Y value is the amount of threat it produces or removes from all actors.  In the above example we made four different skills.  Skill 1 would be an example of a skill that produces no threat for the actor.  Skill 2 is an example of a skill that produces quite a bit of threat.  Skill 3 is a skill that removes all threat from the actor, and skill 4 would produce threat for the actor while removing threat from all actors.



Changes to Battle Screen

Finally, there needs to be a visual representation of how much threat each character has generated.  Below is a screen shot of what I have in mind (I'm using ParaDog's Active Time Battle System v. 2.58, by the way, and a copy can be found at http://rmrk.net/index.php?topic=14056.0):

(http://i423.photobucket.com/albums/pp317/KCMike20/RMXP1.jpg)


Excuse the bad picture.  I just drew up something simple in paint before posting.  On the right side of the screen you can see a small box has been added that uses gauges to keep track of the amount of threat each actor has.  Notice how there is a fourth gauge, but there is no fourth actor in the party.  That's my mistake.   :roll:  If the extremely benevolent person who decides to script this can make it so the number of gauges shown is equal to the number of actors in the party (I.E., if you only have two actors, only two gauges are drawn), then that would be perfect!

Thanks so much in advance, and hopefully there is someone out there nice of to take this over.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on January 04, 2009, 08:24:55 am
I don't know the ideal way to do it, but I can try to get it to work.

@Anyone who knows how:

Quoteand enemy actors always target the party member with the highest threat when attacking (or if two actors have the same value, the target is randomly selected between the two).


I've defined the "threat" variable for the Game_Actor class. Next, I modified the Game_Party#random_target_actor method. I collected the valid actors in an array and sorted it by their threats, like this:


class Game_Party
 
  alias fts_threat_choose_actor random_target_actor
  def random_target_actor(hp0 = false)
    # Decide valid targets
    targets = []
    @actors.each {|actor|
    targets.push(actor) if (!hp0 && actor.exist?) || (hp0 && actor.hp0?)}
    return fts_threat_choose_actor(hp0) if targets.size == 0
    # Decide target by their threat
    targets.sort! {|a, b| b.threat - a.threat}
    ############################################
    return fts_threat_choose_actor(hp0)
  end
 
end


After that, I could return the first actor in the target array, but that would not chose randomly b/w actors with same threat. How do I proceed?
Also, is that method the structurally right one to modify?
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Kagutsuchi on January 07, 2009, 03:32:16 am
Thats a brilliant idea! I'm so tired of the uselessness of a "tank class" because it is noway to make the opponent attack the tank more often than the cloth wearers (the front, middle and rear system doesn't work at all!) <.<

Add-on that allows you to create skills that generate extra aggro/treat would be great.

@Fantasist, does that script work as it is now? or is it incomplete?
(excluding the choose randomly b/w actors with same threat part, that is not so important imo)
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: KCMike20 on January 07, 2009, 05:31:15 am
I'm glad someone else is excited about this idea!  I was beginning to think I might be the only one.  : P

From a design standpoint, it does add an important aspect of player control to the battle system (which is generally regarded as a good idea).  It makes players consider the risk of using certain abilities and determine if that's a risk their willing to take.  I think it's a system with a lot of potential.

No rush, Fantasist, but just to appease inquiring minds, how is the script coming along?
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on January 07, 2009, 09:27:55 am
lol! I was going to get to it eventually. This is actually implemented (as an addon?) in the RTAB. I saw it waaaaaaay back when I had no clue about scripting and decided to get back to it.

Anyway, I haven't tested this extensively, this is not even version 0.5 :P And I'm not too experienced with the battle system, this attempt is my best guess. I can't guarantee the above code works, so don't use it yet.

Quote from: Kagutsuchi@Fantasist, does that script work as it is now? or is it incomplete?
(excluding the choose randomly b/w actors with same threat part, that is not so important imo)

Not so important if you're OK with the enemies always attacking the first actor in the line even if everyone has the same threat :P

So, any ideas? Or maybe I can find some examples in the default scripts.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Kagutsuchi on January 07, 2009, 03:07:18 pm
Quote from: Fantasist on January 07, 2009, 09:27:55 am
lol! I was going to get to it eventually. This is actually implemented (as an addon?) in the RTAB. I saw it waaaaaaay back when I had no clue about scripting and decided to get back to it.

Anyway, I haven't tested this extensively, this is not even version 0.5 :P And I'm not too experienced with the battle system, this attempt is my best guess. I can't guarantee the above code works, so don't use it yet.

Quote from: Kagutsuchi@Fantasist, does that script work as it is now? or is it incomplete?
(excluding the choose randomly b/w actors with same threat part, that is not so important imo)

Not so important if you're OK with the enemies always attacking the first actor in the line even if everyone has the same threat :P

So, any ideas? Or maybe I can find some examples in the default scripts.


Well that wouldn't be a problem if none have the same treat :P
I know nothing about scripting =D
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: KCMike20 on January 31, 2009, 10:30:38 pm
Bumpity bump bump.

Is there anyone out there who can script this?
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on January 31, 2009, 11:15:13 pm
1. Sorry, I totally forgot about this >.<
2. I still don't know what to do to select random actors with the same threat.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Calintz on January 31, 2009, 11:40:47 pm
This is neat though...
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: KCMike20 on February 01, 2009, 01:06:59 am
Quote from: Fantasist on January 31, 2009, 11:15:13 pm
1. Sorry, I totally forgot about this >.<
2. I still don't know what to do to select random actors with the same threat.



Do you think you could get it to work if we removed the "random actor" bit?  For example, having the script just call the first actor (either in regards to database ID or perhaps actor position in battle) with the highest threat? 
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on February 01, 2009, 09:27:43 am
Yes, but I don't like that one bit. OK, so I have exams for the next 3 days, so I think I'll work on it this weekend. Also, I PMed Bliz about something else abd he hasn't responded. When he's active again, I'll take his advice. Basically, if you have some time, know that I'm still on this, cause I like the idea very much.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Kagutsuchi on February 04, 2009, 02:15:19 pm
Wouldn't it be possible to create something which every turn generates between 1-10 random threat by each actor? This way the odds for two actors to have the same aggro will be drastically lowered.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on February 04, 2009, 10:30:23 pm
But that would ruin the whole point of this script :P
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Starrodkirby86 on February 04, 2009, 10:36:33 pm
Maybe we can further incorporate that when it comes to the threats for actors of the same threat level...? Or it goes even more in-depth, looking into stats or even battle formations to see if that player is a threat. Or...rather...you can configure it to what hero is at a threat, maybe what level or how their welfare is...?

Or is that still too hard for you Fanta...?
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on February 05, 2009, 04:43:18 am
I figured it out! It's so simple, I can't believe I didn't think of it earlier >.<

@KCMike:
So only skills can modify the threat. Max threat should be defined. I'm also assuming minimum threat is 0. This should be done soon.

EDIT:
Okay, I've succesfully implemented everything including the config system. But lets say you use a skill and it misses. Do you want missed skills to change the threat level or do the skills have to deal damage?
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: KCMike20 on February 05, 2009, 06:36:26 pm
Quote from: Fantasist on February 05, 2009, 04:43:18 am

EDIT:
Okay, I've succesfully implemented everything including the config system. But lets say you use a skill and it misses. Do you want missed skills to change the threat level or do the skills have to deal damage?



Fantasist, this made my day!  I can't wait to try out the finished script!

Also, this is a very good question.  I know other people are interested in this script, and I don't want to ruin the scripts functionality based on what I had in mind but...Personally, I still would like missed skills to generate threat.  Hey, if somebody shot an arrow at me, and it missed and hit a nearby tree instead, I'd still think I'd be pretty pissed.  Either way, I still think some abilities, such as strong status effects, should cause threat too, so I say yes, skills should be able to draw threat whether they inflict damage or not.


EDIT: I hate to throw this out there before I've seen the finished script, but do you think it's possible to implement skills that remove a certain amount of threat when you target a party member?  For example, we could make a skill called "Pacify" that removes 10 threat from whoever the target is.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on February 06, 2009, 05:35:56 am
QuotePersonally, I still would like missed skills to generate threat.  Hey, if somebody shot an arrow at me, and it missed and hit a nearby tree instead, I'd still think I'd be pretty pissed.  Either way, I still think some abilities, such as strong status effects, should cause threat too, so I say yes, skills should be able to draw threat whether they inflict damage or not.

That's what I had in mind too :)

QuoteEDIT: I hate to throw this out there before I've seen the finished script, but do you think it's possible to implement skills that remove a certain amount of threat when you target a party member?  For example, we could make a skill called "Pacify" that removes 10 threat from whoever the target is.

Yeah, I can work on that. As things stand now, I'll finish this before Sunday.

EDIT:
I hit a hitch again. I need to analyze something closely. It could take a bit long, but it's highly unlikely.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: KCMike20 on February 21, 2009, 02:41:21 pm
Quote from: Fantasist on February 06, 2009, 05:35:56 am

QuoteEDIT: I hate to throw this out there before I've seen the finished script, but do you think it's possible to implement skills that remove a certain amount of threat when you target a party member?  For example, we could make a skill called "Pacify" that removes 10 threat from whoever the target is.
Yeah, I can work on that. As things stand now, I'll finish this before Sunday.

EDIT:
I hit a hitch again. I need to analyze something closely. It could take a bit long, but it's highly unlikely.




I'm guessing that hitch struck hard.  How goes the progress on this?
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on February 22, 2009, 12:37:43 am
How goes the progress... my laptop where I have your project is busted, it's not starting up. I had to reinstall XP on my desktop due to it's unbearable annoyances. Do you have a deadline for this?

EDIT:
And of course, I still haven't found a way around the hitch I was talking about.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: KCMike20 on February 22, 2009, 03:27:15 am
Yikes!  So sorry to hear the bad news.

Nope, no deadline.  I was just trying to quell my fear that this thread had been forgotten about.   :^_^':
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on February 22, 2009, 07:25:33 am
I tend to do that, sorry ^_^'
*sigh* I'll have to complete this system sooner or later: I planned on using this in my game long ago since I saw it in the RTAB demo. I'll do it, you can be sure of that :up:
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: KCMike20 on May 09, 2009, 07:56:36 am
[Invisibump]  :^_^':
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Jackolas on June 26, 2009, 05:49:00 am
can i bumb this 1 becouse it was 1 of the more interesting requests
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Holyrapid on July 06, 2009, 01:32:28 pm
Im bumpng it too, because this would be nice with BABS... I know it has some sort of threat thing in it allready, but from my knowledge, this would improve it.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 06, 2009, 03:55:17 pm
I don't know what you said about BABS, but this sure is a great system. I wish I could do it soon.
Can someone help me on this? I don't know how to choose randomly b/w actors with same threat. Like say the threats of the party members are 6, 6, 4, 2. The target should be either the 1st or second actor. How do I get that?
Also, if anyone can do this completely, I'll gladly hand over the responsibility.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Starrodkirby86 on July 06, 2009, 04:02:18 pm
I'm no scripting wizard, the best I can do is script you a Pikachu, but have you tried something like...

When in the case that there's two, three, or four actors with equal threat amounts, perhaps you can generate a random variable of 1, 2, 3, and 4. Whichever variable it lands on would be the monster would attack...Of course it might turn out to be very unoptimized or so (4! = 24 [If you see no relation to this thing, then ignore this]), but bah.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: winkio on July 06, 2009, 04:06:52 pm
make an array of the targets.  Then choose a random number from the indexes

Example:

possible_targets = []
possible_targets.push(actor1)
possible_targets.push(actor3)
possible_targets.push(actor4)
the_target = possible_targets[rand(possible_targets.size)]

that's pseudocode, but its pretty close to actual code.

And if you want to give this away at some point, I have the time and could do it.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 06, 2009, 04:11:01 pm
@Star: Doesn't really help, but thanks. (Script me a Pikachu.)

@winkio: Yes, but I need to separate the equal threat actors to choose randomly among them.

*sigh* I don't know if it's the phobia of not completing this for 6 months, but I'm kind of afraid even to start. screw it. I'll try this again from scratch.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Starrodkirby86 on July 06, 2009, 04:12:57 pm
Quote from: Fantasist on July 06, 2009, 04:11:01 pm
@Star: Doesn't really help, but thanks. (Script me a Pikachu.)

Quote from: Starrodkirby86 on July 05, 2008, 11:03:25 am
Quote from: Fantasist on July 05, 2008, 10:58:30 am
lol! Then script me a pikachu!

Okay...um...
#Pikachu Code
#By Starrodkirby86
#Pika Pika! Insert this above main! You'll be happy!
#Instructions:
#
#Place this ABOVE Main. You'll be happy
begin
  print "Pikachu loves hentai."
end

Title: Re: Script Request: Threat/Aggro System [XP]
Post by: winkio on July 06, 2009, 04:19:43 pm
okay, ill write pretty much the whole thing out:

threat = []
alive_actors = []
$game_party.actors.each {|a|
 if (!a.is_dead)
   threat.push(a.get_threat)
   possible_targets.push(a)
 end}
possible_targets = []
(0...threat.size).each {|i|
 if threat[i] == threat.max
   possible_targets.push(alive_actors[i])
 end}
the_target = possible_targets[rand(possible_targets.size)]

Iterate through all the actors, add any that can be targeted to an array, and also add their threats to a different array.  Find the max of the threat array, and push the corresponding actor(s) into a new array.  Take a random element of that array for the target.
 
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Blizzard on July 06, 2009, 04:25:09 pm
Use .sort with a block that specifies how the array should be sorted (as in: what the sorting criteria is). Just check out "CP#resort_weapons" in CP Beta.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 06, 2009, 04:40:51 pm
That was the first thing I tried:
targets.sort! {|a, b| b.threat - a.threat}

It still doesn't solve the problem of deciding b/w 2 or more actors of same highest threat.

This is the solution I came up with just now:

  def random_target_actor(hp0 = false)
    # Get maximum threat
    max_threat = 0
    for actor in @actors
      next unless (!hp0 && actor.exist?) || (hp0 && actor.hp0?)
      max_threat = actor.threat if actor.threat > max_threat
    end
    # Collect targets with maximum threats
    targets = []
    for actor in @actors
      next unless (!hp0 && actor.exist?) || (hp0 && actor.hp0?)
      targets.push(actor) if actor.threat == max_threat
    end
    return fts_threat_choose_actor(hp0) if targets.size == 0
    return targets[rand(targets.size)]
  end


1st, I get the max threat. Then I collect actors with max threat. The array size will be 1 or more, but chosing a random element will work in either case.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: winkio on July 06, 2009, 04:50:37 pm
yes it will.  Good job.   :)
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Blizzard on July 06, 2009, 04:52:31 pm
Or

targets.sort! {|a, b| b.threat - a.threat}
targets = targets.find_all {|a| a.threat == targets[0].threat}
target = targets[rand(targets.size)]


:P
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: winkio on July 06, 2009, 04:55:12 pm
damn you blizz, and your extensive knowledge of coding!

(seriously, who knew about find_all?)
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 06, 2009, 04:56:16 pm
@Blizz: Where do you learn these subtle details?

m(_)m  m(_)m  m(_)m
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Blizzard on July 06, 2009, 05:02:44 pm
Spoiler: ShowHide
(http://img257.imageshack.us/img257/650/snap894.png)


@winkio: Careful, not "find_all?" but "find_all". I use "find_all" all the time along with "any?". I prefer "x.any? {|a| !a.condition}" to "x.all? {|a| a.condition}" because "any?" will abort the search if the first one was found while "all?" always has to check all.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: winkio on July 06, 2009, 05:07:50 pm
the ? was because I was asking a question...
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Blizzard on July 06, 2009, 05:10:41 pm
Ok, no problem. It's just that I got an error a few times by using find_all? accidentally. xD
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: winkio on July 06, 2009, 05:12:32 pm
yeah, punctuation sucks.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 06, 2009, 05:14:36 pm
The RMXP help file... *levels up*

EDIT:

New question. How do I determine if a skill is offensive? Like deals damage or applies a negative status effect? Or should I just make user configuration to let them decide which skills raise or reduce threat?
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Blizzard on July 06, 2009, 05:22:03 pm
skill = $data_skills[ID]
if skill.power > 0 # offensive
end
if skill.plus_state_set.size > 0 # inflicts states
end
if (skill.plus_state_set & [BAD_STATE_ID1, BAD_STATE_ID2, BAD_STATE_ID3]).size > 0 # inflicts "bad" states
end
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: winkio on July 06, 2009, 05:25:10 pm
A configurable option that would be nice:

In some games, the healer has a very high aggro (most of the examples in my mind are mmos).  It would be a nice option to choose whether or not healers get high threat.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 06, 2009, 05:31:30 pm
@winkio: I think I'll use both. Threat increases in the skill is offensive AND if it's included in a list of threat-raising skills. I could also check the skill's scope.

@Blizz: Thanks Blizz :) *goes off to modify skill_effect*

PS: This topic is so active today, wink or Blizz always posted before I did >.<
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: winkio on July 06, 2009, 05:35:20 pm
That's because I'm bored and am trying to get back into scripting like I get into swimming pools: with your m-- I mean by jumping in.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Ryex on July 06, 2009, 05:36:00 pm
this will be a great system, one quick question is it going to have the threat displayed or is it going to be a back ground system, it doesn't matter much as i can edit it to my liking either way if you release it, but I kinda want to know.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Blizzard on July 06, 2009, 05:41:04 pm
I didn't sleep much last night so I'm not really capable of anything useful. *coughs at actual scripts and the new Blizz-ABS plugin* <_<; Erm... Ignore those.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 06, 2009, 05:46:55 pm
@Blizz: And I'm depriving myself of sleep right now O.O

@Ryex: I plan to make some sort of display for the DBS, but I haven't decided the layout yet.

Stop watching this topic for now guys. I've been working on the transitions thingy alongside this and I'm about to post the undocumented version:
http://forum.chaos-project.com/index.php?topic=1390.0
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: G_G on July 06, 2009, 09:16:13 pm
if anything fant heres this as well
it was in Game_Troop
  def random_target_enemy(hp0 = false)
   # Initialize roulette
   roulette = []
   # Loop
   for enemy in @enemies
     # If it fits the conditions
     if (not hp0 and enemy.exist?) or (hp0 and enemy.hp0?)
       # Add an enemy to the roulette
       roulette.push(enemy)
     end
   end
   # If roulette size is 0
   if roulette.size == 0
     return nil
   end
   # Spin the roulette, choose an enemy
   return roulette[rand(roulette.size)]
 end
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 09, 2009, 01:02:53 pm
I think that method is executed when a skill/status's scope is "Attack all enemies", am I right? If so, then it has nothing to do with this system.

Anyway, I completed the first draft. Here it is:

Spoiler: ShowHide

module ThreatConfig
  #--------------------------------------------------------------------------
  # * Config
  #--------------------------------------------------------------------------
  ThreatChance = 100 # The chance of enemies attacking based on threat
  #--------------------------------------------------------------------------
  # * Get the threat attribute
  #--------------------------------------------------------------------------
  attr_reader :threat
  def self.get_skill_threat(skill_id)
    threat = case skill_id
    # when skill_ID then [ user_threat, party_threat ]
    when 57 then [10, -2]
    else false
    end
    return threat
  end
  #--------------------------------------------------------------------------
  # * Get the threat attribute
  #--------------------------------------------------------------------------
  attr_reader :threat
  def self.get_item_threat(item_id)
    threat = case item_id
    # when item_ID then [ user_threat, party_threat ]
    when 33 then [10, -20]
    else false
    end
    return threat
  end
  #:::::::::::::: Don't touch these yet ::::::::::::::
  MaxThreat = 100
  MinThreat = 0
  AutoDetect = false # Automatically determine if a skill or item is dangerous
end
#==============================================================================
# ** Game_Actor
#==============================================================================
class Game_Actor
  #--------------------------------------------------------------------------
  # * Initialize threat attribute
  #--------------------------------------------------------------------------
  alias game_actor_threat_setup setup
  def setup(actor_id)
    @threat = 0
    game_actor_threat_setup(actor_id)
  end
  #--------------------------------------------------------------------------
  # * Get the threat attribute
  #--------------------------------------------------------------------------
  attr_reader :threat
  #--------------------------------------------------------------------------
  # * Set the threat attribute
  #--------------------------------------------------------------------------
  def threat=(val)
    max = ThreatConfig::MaxThreat
    min = ThreatConfig::MinThreat
    val = max if val > max
    val = min if val < min
    @threat = val
  end
  #--------------------------------------------------------------------------
  # * Threat at battle start
  #--------------------------------------------------------------------------
  def start_threat
    actor_id = self.id
    threat = case actor_id
    when 1 then 6
    when 2 then 7
    when 7 then 6
    else 0
    end
    return threat
  end
end
#==============================================================================
# ** Game_Party
#==============================================================================
class Game_Party
  #--------------------------------------------------------------------------
  # * Choose actor by threat
  #--------------------------------------------------------------------------
  alias choose_actor_by_threat random_target_actor
  def random_target_actor(hp0 = false)
    if rand(100) >= ThreatConfig::ThreatChance
      return choose_actor_by_threat(hp0)
    end
    # Collect valid actors
    targets = []
    for actor in @actors
      next unless (!hp0 && actor.exist?) || (hp0 && actor.hp0?)
      targets.push(actor)
    end
    # Get actors with maximum threat
    targets.sort! {|a, b| b.threat - a.threat}
    targets = targets.find_all {|a| a.threat == targets[0].threat}
    # Choose random
    target = targets[rand(targets.size)]
    return target
  end
end
#==============================================================================
# ** Game_Battler
#==============================================================================
class Game_Battler
  #--------------------------------------------------------------------------
  # * Attack Threat
  #--------------------------------------------------------------------------
  alias attack_effect_threat attack_effect
  def attack_effect(attacker)
    attacker.threat += 1 if attacker.is_a?(Game_Actor)
    attack_effect_threat(attacker)
  end
  #--------------------------------------------------------------------------
  # * Skill Threat
  #--------------------------------------------------------------------------
  alias skill_effect_threat skill_effect
  def skill_effect(user, skill)
    threat = user.is_a?(Game_Actor) && ThreatConfig.get_skill_threat(skill.id)
    if threat
      user_threat, party_threat = threat[0], threat[1]
      for actor in $game_party.actors
        threat_plus = actor.id == user.id ? user_threat : party_threat
        actor.threat += threat_plus
      end
    end
    skill_effect_threat(user, skill)
  end
end
#==============================================================================
# ** Scene_Battle
#==============================================================================
class Scene_Battle
  #--------------------------------------------------------------------------
  # * Defend Threat
  #--------------------------------------------------------------------------
  alias basic_action_threat_result make_basic_action_result
  def make_basic_action_result
    if @active_battler.current_action.basic == 1 &&
      @active_battler.is_a?(Game_Actor)
       @active_battler.threat -= 1
    end
    basic_action_threat_result
  end
  #--------------------------------------------------------------------------
  # * Item Threat
  #--------------------------------------------------------------------------
  alias item_action_threat_result make_item_action_result
  def make_item_action_result
    item_action_threat_result
    threat = @active_battler.is_a?(Game_Actor) && ThreatConfig.get_item_threat(@item.id)
    if threat
      user_threat, party_threat = threat[0], threat[1]
      for actor in $game_party.actors
        threat_plus = actor.id == @active_battler.id ? user_threat : party_threat
        actor.threat += threat_plus
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Clear threats before battle
  #--------------------------------------------------------------------------
  alias clear_threats_start_phase1 start_phase1
  def start_phase1
    clear_threats_start_phase1
    $game_party.actors.each {|actor| actor.threat = actor.start_threat}
  end
end

class Window_Threat < Window_Base
 
  H = 20
 
  def initialize(x, y, w)
    super(x, y, w, 32 + actors.size * H)
    @threats = []
    actors.each {|a| @threats.push(a.threat)}
    self.contents = Bitmap.new(w-32, self.height-32)
    self.contents.font.size = H
    self.contents.font.bold = H <= 22
    refresh
  end
 
  def refresh
    self.contents.clear
    actors.each_with_index {|a, i|
    self.contents.draw_text(0, i*H, self.width-32, H, a.name)
    self.contents.draw_text(0, i*H, self.width-32, H, @threats[i].to_s, 2)
    }
  end
 
  def update
    flag = false
    actors.each_with_index {|a, i|
    @threats[i] = a.threat if a.threat != @threats[i]
    flag = true}
    refresh if flag
  end
 
  def actors
    return $game_party.actors
  end
 
end

class Scene_Battle
 
  alias threat_win_init main
  def main
    @threat_win = Window_Threat.new(0, 64, 160)
    threat_win_init
    @threat_win.dispose
  end
 
  alias threat_win_upd update
  def update
    @threat_win.update
    threat_win_upd
  end
 
end


Features:



As for the skill and item config, here's a quote from the original request:

Quote
When ID then return [[X, Y]]

when 1 then return [[0, 0]]
when 2 then return [[50, 0]]
when 3 then return [[-100, 0]]
when 4 then return [[30, -10]]

This script allows the user to determine the maximum threat possible as well as the amount of threat each skill produces or removes from the actor using it.  The ID is the ID Number of the skill in the database, the X value is the amount of threat a skill produces (or removes) for the actor using it and the Y value is the amount of threat it produces or removes from all actors.  In the above example we made four different skills.  Skill 1 would be an example of a skill that produces no threat for the actor.  Skill 2 is an example of a skill that produces quite a bit of threat.  Skill 3 is a skill that removes all threat from the actor, and skill 4 would produce threat for the actor while removing threat from all actors.

The config is similar.

So anyone who's interested, please try it and test it to your content. I'd be happy to correct and improve this system :)
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Holyrapid on July 09, 2009, 01:14:37 pm
I´ll try this. This will be extra nice for abs game. Or does this work with babs allready? Or do i need a plugin?
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 09, 2009, 01:21:41 pm
You know, good point. Frankly, I have no idea if this works with BABS. I'm taking a rough guess that it should, but for now, it's intended for the DBS.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Holyrapid on July 09, 2009, 01:27:35 pm
Well, i´ll try it and tell you if it works or not.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 09, 2009, 01:31:11 pm
Wait, I just realized. This will most likely NOT work with BABS.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Holyrapid on July 09, 2009, 01:35:05 pm
Yea, it just gave me error of line 34. and all it says on that line is end... too bad.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 09, 2009, 01:39:39 pm
Wait, what!? Did it say a Syntax Error? nvm, I'll look into it.

EDIT: No syntax error in the script I posted above. I guess it's not compatible with BABS just yet.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Jackolas on July 10, 2009, 04:43:16 pm
Fantasist. did I already say your brilliant?
script works like a dream... better even

just 1 question
i know u have defined MaxThreat = 100
what happens when you hit 100 threat.. ore if 2 players hit it?


Edit to more bug testing etc:

first 1 is... players can get -Aggro. its only not displayed... for example... if I use a skill that is doing -10 while i have 1 aggro. i can do 9 attacks before my aggro go's above 0

Second (not a major 1).. the main aggro target is picked at the beginning of the  turn and dos not regonise changes in aggro in the turn. example:
Spoiler: ShowHide
aggro begin turn is:
player 1 - 1 agro
player 2 - 5 agro
player 3 - 0 agro

first turn begins.
Player 1 attacks and gains till 20 agro.
player 2 defends and gains till 8 agro.
enemy attacks player 2 while player 1 has almost double aggro (because begin of turn player 2 had most aggro)
player 3 attacks and gains till 3 aggro.

next turn.
player 1 use skill and loses till 10 aggro
player 2 attacks and gains till 15 aggro
enemy attacks player 1 (same reason turn 1)
player 3 attacks and gains till 2 agro.

hope its clear
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 11, 2009, 04:47:08 am
Thanks for the praise and feedback Jackolas :)

Quotewhat happens when you hit 100 threat.. ore if 2 players hit it?

Nothing. The threat won't go any higher than that. It's more of a technical setting than a configurable option. I might remove it eventually (and make the threat range 0-100) (and remove the limit for the highest threat).

QuoteSecond (not a major 1).. the main aggro target is picked at the beginning of the  turn and dos not regonise changes in aggro in the turn.

Thanks for pointing it out, I'll fix it. It IS a major issue btw.

EDIT:

OK, I fixed the above issue, now any changes in threat in the current turn are considered by the enemies.

Spoiler: ShowHide

module ThreatConfig
  #--------------------------------------------------------------------------
  # * Config
  #--------------------------------------------------------------------------
  ATTACK_THREAT = 1 # Threat to increase when actor attacks
  DEFEND_THREAT = 1 # Threat to decrease when actor defends
  THREAT_CHANCE = 100 # The chance of enemies attacking based on threat
 
  def self.get_skill_threat(skill_id)
    threat = case skill_id
    #========================================================================
    # SKILL THREAT CONFIG BEGIN
    #========================================================================
    when 57 then [10, -2]
    # when skill_ID then [ user_threat, party_threat ]
    #========================================================================
    # SKILL THREAT CONFIG END
    #========================================================================
    else false
    end
    return threat
  end
 
  def self.get_item_threat(item_id)
    threat = case item_id
    #========================================================================
    # SKILL THREAT CONFIG BEGIN
    #========================================================================
    when 33 then [10, -20]
    # when item_ID then [ user_threat, party_threat ]
    #========================================================================
    # SKILL THREAT CONFIG END
    #========================================================================
    else false
    end
    return threat
  end
end

#==============================================================================
# ** Game_Actor
#==============================================================================
class Game_Actor
  #--------------------------------------------------------------------------
  # * Initialize threat attribute
  #--------------------------------------------------------------------------
  alias game_actor_threat_setup setup
  def setup(actor_id)
    @threat = 0
    game_actor_threat_setup(actor_id)
  end
  #--------------------------------------------------------------------------
  # * Get the threat attribute
  #--------------------------------------------------------------------------
  attr_reader :threat
  #--------------------------------------------------------------------------
  # * Set the threat attribute
  #--------------------------------------------------------------------------
  def threat=(val)
    val = 0 if val < 0
    @threat = val
  end
  #--------------------------------------------------------------------------
  # * Threat at battle start
  #--------------------------------------------------------------------------
  def start_threat
    actor_id = self.id
    threat = case actor_id
    when 1 then 6
    when 2 then 7
    when 7 then 6
    else 0
    end
    return threat
  end
end
#==============================================================================
# ** Game_Party
#==============================================================================
class Game_Party
  #--------------------------------------------------------------------------
  # * Choose actor by threat
  #--------------------------------------------------------------------------
  alias choose_actor_threat_orig random_target_actor
  def random_target_actor(hp0 = false)
    if rand(100) >= ThreatConfig::THREAT_CHANCE
      return choose_actor_threat_orig(hp0)
    else
      return threat_target_actor(hp0)
    end
  end
  #--------------------------------------------------------------------------
  # * Calculate threat and choose actor
  #--------------------------------------------------------------------------
  def threat_target_actor(hp0=false)
    # Collect valid actors
    targets = []
    for actor in @actors
      next unless (!hp0 && actor.exist?) || (hp0 && actor.hp0?)
      targets.push(actor)
    end
    # Get actors with maximum threat
    targets.sort! {|a, b| b.threat - a.threat}
    targets = targets.find_all {|a| a.threat == targets[0].threat}
    # Choose random
    target = targets[rand(targets.size)]
    return target
  end
end
#==============================================================================
# ** Game_Battler
#==============================================================================
class Game_Battler
  #--------------------------------------------------------------------------
  # * Attack Threat
  #--------------------------------------------------------------------------
  alias attack_effect_threat attack_effect
  def attack_effect(attacker)
    attacker.threat += ThreatConfig::ATTACK_THREAT if attacker.is_a?(Game_Actor)
    attack_effect_threat(attacker)
  end
  #--------------------------------------------------------------------------
  # * Skill Threat
  #--------------------------------------------------------------------------
  alias skill_effect_threat skill_effect
  def skill_effect(user, skill)
    threat = user.is_a?(Game_Actor) && ThreatConfig.get_skill_threat(skill.id)
    if threat
      user_threat, party_threat = threat[0], threat[1]
      for actor in $game_party.actors
        threat_plus = actor.id == user.id ? user_threat : party_threat
        actor.threat += threat_plus
      end
    end
    skill_effect_threat(user, skill)
  end
end
#==============================================================================
# ** Scene_Battle
#==============================================================================
class Scene_Battle
  #--------------------------------------------------------------------------
  # * Defend Threat
  #--------------------------------------------------------------------------
  alias basic_action_threat_result make_basic_action_result
  def make_basic_action_result
    if @active_battler.current_action.basic == 1 && @active_battler.is_a?(Game_Actor)
      @active_battler.threat -= ThreatConfig::DEFEND_THREAT
    end
    basic_action_threat_result
  end
  #--------------------------------------------------------------------------
  # * Item Threat
  #--------------------------------------------------------------------------
  alias item_action_threat_result make_item_action_result
  def make_item_action_result
    item_action_threat_result
    threat = @active_battler.is_a?(Game_Actor) && ThreatConfig.get_item_threat(@item.id)
    if threat
      user_threat, party_threat = threat[0], threat[1]
      for actor in $game_party.actors
        threat_plus = actor.id == @active_battler.id ? user_threat : party_threat
        actor.threat += threat_plus
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Choose target actor in realtime
  #--------------------------------------------------------------------------
  alias update_phase4_step2_choose_actor_realtime update_phase4_step2
  def update_phase4_step2
    @active_battler.make_action if @active_battler.is_a?(Game_Enemy)
    update_phase4_step2_choose_actor_realtime
  end
  #--------------------------------------------------------------------------
  # * Clear threats before battle
  #--------------------------------------------------------------------------
  alias clear_threats_start_phase1 start_phase1
  def start_phase1
    clear_threats_start_phase1
    $game_party.actors.each {|actor| actor.threat = actor.start_threat}
  end
end

class Window_Threat < Window_Base
 
  H = 20
 
  def initialize(x, y, w)
    super(x, y, w, 32 + actors.size * H)
    @threats = []
    actors.each {|a| @threats.push(a.threat)}
    self.contents = Bitmap.new(w-32, self.height-32)
    self.contents.font.size = H
    self.contents.font.bold = H <= 22
    refresh
  end
 
  def refresh
    self.contents.clear
    actors.each_with_index {|a, i|
    self.contents.draw_text(0, i*H, self.width-32, H, a.name)
    self.contents.draw_text(0, i*H, self.width-32, H, @threats[i].to_s, 2)}
  end
 
  def update
    flag = false
    actors.each_with_index {|a, i|
    @threats[i] = a.threat if a.threat != @threats[i]
    flag = true}
    refresh if flag
  end
 
  def actors
    return $game_party.actors
  end
 
end

class Scene_Battle
 
  alias threat_win_init main
  def main
    @threat_win = Window_Threat.new(0, 64, 160)
    threat_win_init
    @threat_win.dispose
  end
 
  alias threat_win_upd update
  def update
    @threat_win.update
    threat_win_upd
  end
 
end
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Holyrapid on July 13, 2009, 10:19:08 am
I take it, that it´s not BABS compatible yet?
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 13, 2009, 10:27:17 am
Nope. And I don't think I will be doing it. Make a request in the script request forum, I'd like to see it in BABS :)

Oh, don't do it until I release the script. I'm documenting and fine-tuning the script right now.
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Jackolas on July 13, 2009, 12:03:57 pm
started testing the new script..

Edit:

First of all.. works like a dream.. all bugs gone.

second is a question. You already removed the 100 aggro lvl?
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 13, 2009, 12:32:21 pm
Yes I did, but the lowest threat is still 0. I'm also done furnishing the script, I will be posting it now. Thanks for testing Jackolas :)

EDIT:

It's done. Here's the topic:

http://forum.chaos-project.com/index.php?topic=4174.new#new
Title: Re: Script Request: Threat/Aggro System [XP]
Post by: Starrodkirby86 on July 13, 2009, 07:22:16 pm
Marking as [RESOLVED], you outdid yourself you lovable scamp. I recommend possibly contacting Mike that the script is done, if he's still interested in RMXP.
Title: Re: [RESOLVED] Script Request: Threat/Aggro System [XP]
Post by: Fantasist on July 14, 2009, 08:16:28 am
You know, I almost forgot about that. Thanks for reminding me :)
Title: Re: [RESOLVED] Script Request: Threat/Aggro System [XP]
Post by: Seox on July 14, 2009, 12:12:07 pm
I haven't read any of the replies due to laziness, but let me just SINCERILY compliment you on the descriptiveness of your request. You DESERVED the script, since you put so much into the topic. Trust me, scripting is a bitch unless you know what you're doing, exactly - bad topics don't help. Thank you.