[RESOLVED] Script Request: Threat/Aggro System [XP]

Started by KCMike20, January 04, 2009, 06:33:00 am

Previous topic - Next topic

KCMike20

January 04, 2009, 06:33:00 am Last Edit: July 13, 2009, 07:22:31 pm by Starrodkirby86
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):




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.

Fantasist

January 04, 2009, 08:24:55 am #1 Last Edit: January 04, 2009, 08:55:35 am by Fantasist
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?
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Kagutsuchi

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)

KCMike20

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?

Fantasist

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.
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Kagutsuchi

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

KCMike20

Bumpity bump bump.

Is there anyone out there who can script this?

Fantasist

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 like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Calintz


KCMike20

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? 

Fantasist

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.
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Kagutsuchi

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.

Fantasist

But that would ruin the whole point of this script :P
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Starrodkirby86

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...?

What's osu!? It's a rhythm game. Thought I should have a signature with a working rank. ;P It's now clickable!
Still Aqua's biggest fan (Or am I?).




Fantasist

February 05, 2009, 04:43:18 am #14 Last Edit: February 05, 2009, 05:59:56 am by Fantasist
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?
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




KCMike20

February 05, 2009, 06:36:26 pm #15 Last Edit: February 05, 2009, 06:41:12 pm by KCMike20
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.

Fantasist

February 06, 2009, 05:35:56 am #16 Last Edit: February 06, 2009, 07:23:48 am by Fantasist
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.
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




KCMike20

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?

Fantasist

February 22, 2009, 12:37:43 am #18 Last Edit: February 22, 2009, 12:42:34 am by Fantasist
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.
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




KCMike20

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.   :^_^':

Fantasist

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:
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews





Jackolas

can i bumb this 1 becouse it was 1 of the more interesting requests

Holyrapid

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.

Fantasist

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.
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Starrodkirby86

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.

What's osu!? It's a rhythm game. Thought I should have a signature with a working rank. ;P It's now clickable!
Still Aqua's biggest fan (Or am I?).




winkio

July 06, 2009, 04:06:52 pm #26 Last Edit: July 06, 2009, 04:08:12 pm by winkio
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.

Fantasist

@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.
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Starrodkirby86

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


What's osu!? It's a rhythm game. Thought I should have a signature with a working rank. ;P It's now clickable!
Still Aqua's biggest fan (Or am I?).




winkio

July 06, 2009, 04:19:43 pm #29 Last Edit: July 06, 2009, 04:24:36 pm by winkio
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.
 

Blizzard

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.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Fantasist

July 06, 2009, 04:40:51 pm #31 Last Edit: July 06, 2009, 04:44:31 pm by Fantasist
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.
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




winkio


Blizzard

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
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

winkio

damn you blizz, and your extensive knowledge of coding!

(seriously, who knew about find_all?)

Fantasist

@Blizz: Where do you learn these subtle details?

m(_)m  m(_)m  m(_)m
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Blizzard

July 06, 2009, 05:02:44 pm #36 Last Edit: July 06, 2009, 05:05:35 pm by Blizzard
Spoiler: ShowHide


@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.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

winkio

the ? was because I was asking a question...

Blizzard

Ok, no problem. It's just that I got an error a few times by using find_all? accidentally. xD
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

winkio


Fantasist

July 06, 2009, 05:14:36 pm #40 Last Edit: July 06, 2009, 05:18:07 pm by Fantasist
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?
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Blizzard

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
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

winkio

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.

Fantasist

@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 >.<
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




winkio

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.

Ryex

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.
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.<br /><br />DropBox, the best free file syncing service there is.<br />

Blizzard

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.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Fantasist

@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
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




G_G

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

Fantasist

July 09, 2009, 01:02:53 pm #49 Last Edit: July 09, 2009, 01:04:18 pm by Fantasist
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:


  • Attacking increases threat by 1
  • Defending decreases threat by 1
  • Using skills changes threat as set in config
  • Using items changes threat as set in config


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 :)
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Holyrapid

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?

Fantasist

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.
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Holyrapid

Well, i´ll try it and tell you if it works or not.

Fantasist

Wait, I just realized. This will most likely NOT work with BABS.
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Holyrapid

Yea, it just gave me error of line 34. and all it says on that line is end... too bad.

Fantasist

July 09, 2009, 01:39:39 pm #55 Last Edit: July 09, 2009, 01:55:44 pm by Fantasist
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.
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Jackolas

July 10, 2009, 04:43:16 pm #56 Last Edit: July 10, 2009, 05:22:46 pm by Jackolas
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

Fantasist

July 11, 2009, 04:47:08 am #57 Last Edit: July 13, 2009, 09:18:13 am by Fantasist
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
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Holyrapid

I take it, that it´s not BABS compatible yet?

Fantasist

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.
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Jackolas

July 13, 2009, 12:03:57 pm #60 Last Edit: July 13, 2009, 12:09:53 pm by Jackolas
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?

Fantasist

July 13, 2009, 12:32:21 pm #61 Last Edit: July 13, 2009, 12:41:30 pm by Fantasist
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
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Starrodkirby86

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.

What's osu!? It's a rhythm game. Thought I should have a signature with a working rank. ;P It's now clickable!
Still Aqua's biggest fan (Or am I?).




Fantasist

You know, I almost forgot about that. Thanks for reminding me :)
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Seox

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.
... (<<<<<<<<<<<<<<< TEH DOTS OF DOOM. Hey, kinda catchy. :naughty:)