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.
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?
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)
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?
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.
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
Bumpity bump bump.
Is there anyone out there who can script this?
1. Sorry, I totally forgot about this >.<
2. I still don't know what to do to select random actors with the same threat.
This is neat though...
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?
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.
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.
But that would ruin the whole point of this script :P
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...?
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?
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.
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.
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?
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.
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. :^_^':
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:
[Invisibump] :^_^':
can i bumb this 1 becouse it was 1 of the more interesting requests
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.
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.
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.
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.
@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.
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
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.
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.
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.
yes it will. Good job. :)
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
damn you blizz, and your extensive knowledge of coding!
(seriously, who knew about find_all?)
@Blizz: Where do you learn these subtle details?
m(_)m m(_)m m(_)m
(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.
the ? was because I was asking a question...
Ok, no problem. It's just that I got an error a few times by using find_all? accidentally. xD
yeah, punctuation sucks.
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?
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
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.
@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 >.<
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.
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 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.
@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
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
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:
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 :)
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?
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.
Well, i´ll try it and tell you if it works or not.
Wait, I just realized. This will most likely NOT work with BABS.
Yea, it just gave me error of line 34. and all it says on that line is end... too bad.
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.
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:
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
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.
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
I take it, that it´s not BABS compatible yet?
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.
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?
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
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.
You know, I almost forgot about that. Thanks for reminding me :)
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.