Help modifying a script - Keeroh - 06-07-2017
Hello!
I have a script that I'm trying to modify that creats a Threat System, so the enemies will focus their attacks on the party member with most threat. During the battle a window appears showing the threat level of each party member. Here is a screen shot:
https://i.imgur.com/m4POIOv.png
What I'm trying to do is removing this window and showing an image next to the party member with most threat. I made a fast edition to show how it would look:
https://i.imgur.com/sGXo6p0.png
Can somoene help me with what I should do to make an image appear and change positions depending on who have the highest threat value? All i know is that removing the end of the code removes the window.
Here is the code:
Code: module ThreatConfig
#--------------------------------------------------------------------------
# * Config
#--------------------------------------------------------------------------
ThreatChance = 80 # 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 97 then [6, 0]
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 2 then 5
when 3 then 5
when 4 then 5
when 5 then 5
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(458, 135, 160) #(458,64,160)
threat_win_init
@threat_win.dispose
end
alias threat_win_upd update
def update
@threat_win.update
threat_win_upd
end
end
Thanks for the attention!
Edit: The images weren't loading for some reason, so I removed them and added a link instead
RE: Help modifying a script - DerVVulfman - 06-09-2017
ROFL. Nice little devil face saying 'Threat'
Haven't had much time to look at it. The magic is actually in the window that renders the Threat scores as indicated in your first screenshot. But instead of making a full 'visible' window, I would make the background & borders invisible and have it drawn horizontally along the bottom edge to overlap the battlers. And I would use the same actor_x value used to render where the battlers are to draw your devil-dude in the window. instead of the scores themselves.
You'd have to 'sort' who the highest threat would be... based on the same generated score. And only show the top scorers. If any have '0' scores, ensure that no devil-dude shows. That's the issue.
The very last section of the code, within Scene_Battle, only activates/deactivates the window and updates it when needed. Without it, there is no Threat system in use at all.
RE: Help modifying a script - Keeroh - 06-10-2017
Haha, thanks! xD
Actually your idea of making the window appear horizontally is very good and less troublesome than making the image appear and move (i think). I managed to remove the background and borders with @threat_win.opacity = 0 and I removed the party member's names commenting self.contents.draw_text(0, i*H, self.width-32, H, a.name), but I don't know exactly how would I change the text color to red and how to position each value horizontally on the right place
RE: Help modifying a script - DerVVulfman - 06-10-2017
Two points.
The Game_Actor class has a method (or def) called screen_x. The method calculates and returns the 'x' position where your battler belongs in the battle-status window. This would be your system to position it horizontally.
The normal code that positions the threat level is
Code: 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
And obviously, if the threat is over the battler, you don't need the name.... so the first 'self.contents.draw_text' isn't needed. You may wanna try this:
Code: def refresh
self.contents.clear
actors.each_with_index {|a, i|
self.contents.draw_text(a.screen_x, 0, self.width-32, H, @threats[i].to_s, 2)
}
end
Notice that I use 'a.screen_x' The a is the individual 'actor' in the actors array. And the a.screen_x refers to the x-location that the given actor needs to be placed.
self.contents.font.color = Color(255,0,0,255) .... that's how you set a font color to red. Using RGBA standards (Red Green Blue Alpha/opacity) in a range of 0-255 each.
RE: Help modifying a script - Keeroh - 06-10-2017
I managed to change the color to red, but when I try using:
Code: def refresh
self.contents.clear
actors.each_with_index {|a, i|
self.contents.draw_text(a.screen_x, 0, self.width-32, H, @threats[i].to_s, 2)
}
end
the threat values disappear
RE: Help modifying a script - DerVVulfman - 06-10-2017
Know what? My bad. The 'self.width-32' is taking the width of the whole window (640 across). The 'h' (or height) should be 32 . And the very last value ( ,2) ) assumes the text is on the right-most area. In essence, it is drawing the threat on the very edge at the right ... if not off the screen. Change the 'self.width-32' into 160, and the very last '2' into a '1'.
Code: self.contents.draw_text(a.screen_x, 0, 160, 32, @threats[i].to_s, 1)
Draw text commands are like this
( X-position, Y-position, width-area, height-of-area, the text, [optional alignment] )
or
( [defined rectangle value], the text, [optional alignment] )
** The '160' is the width of the screen (or 640) divided by 4 (your party size).
** The '32' is the normal height used in a draw-text line. Set it to 16, and you'd likely just see the top half of the text.
** The '1' is the alignment (0 is left justified by default, 1 is centered, 2 is right justified)
Of course, I'm assuming you made the 'threat window stretch across the whole battlesystem screen for this to fit.
RE: Help modifying a script - Keeroh - 06-11-2017
Thanks, I think I understood how it works! I didn't had a clue what those numbers inside the () meant, now it's making more sense
The problem was that I hadn't stretched the threat window. Now that i stretched it and modified the code like you said it's working perfectly!
RE: Help modifying a script - DerVVulfman - 06-11-2017
Great! It would probably have been better if I didn't answer questions while at work, away from my RMXP software.
Still, I like the little devil dude. That would probably take a little more work to have it first 'determine' who has the highest score (or scores if a tie), and use the bitmap drawing code to splat him over the battler. That would entail loading the bitmap from your project (probably in the pictures folder), setting its location, and pasting it within. Sorta like:
Code: # Here, we get the graphic of the Threat Devil Dude, and it's coordinates
ddudebmp RPG::Cache.picture("DevilDude") # Load the pic
ddude_x = a.screen_x # Using 'a' for the actor
ddude_y = 0 # 0 position is top of window
ddude_width = ddudebmp.width # The graphic's width
ddude_height = ddudebmp.height # The Graphic's height
# Here, we make the rectangle drawing area based on the devil dude's dimensions
# Rectangle is defined by ( x, y, width, height) of the area
ddude_rect = Rect.new(0, 0, ddude_width, ddude_height)
# Here, we draw it into the x/y coordinates,
# Blt (or blit) needs: x-position, y-position, the graphic, and rectangle area)
self.contents.blt(ddude_x, ddude_y, ddudebmp, ddude_rect)
But that's the basics, and ya need to deal with sorting WHO gets the hightest threat, and 'IF' it is the highest threat, draw it. Skip if not the highest threat.
|