Submit Your Article


 
RPG Maker

Welcome Guest ( Log In | Register )


  Games Resources RPG Maker VX RPG Maker XP Scripts Tutorials Downloads

 
Closed TopicStart new topic
> Blood & Pain Battle Engine, A different battle concept...
Jens of Zanicuud
post Dec 6 2011, 10:27 AM
Post #1


Dark Jentleman
Group Icon

Group: Local Mod
Posts: 904
Type: Scripter
RM Skill: Skilled
Rev Points: 120




EDITED 8 Dec 2011

RPG Pain & Blood Battle Engine

Author: Jens of Zanicuud
Version: 0.7
Released on: 6 Dec 2011
Terms of use: Free use, just credit; for commercial use, you have to ask for permission.
Customization: Free, just link the mod version in this topic...
FAQ or help: Manual is posted here as well, feel free to ask for everything.

Hello everyone, I'm posting the script I announced in this topic:

Blood & Pain System

This is the user's manual... read carefully if you aren't accostumed with scripting or simply want to know how it works.

User's Manual
– Instructions for Blood & Pain system:
by Jens of Zanicuud, V 0.7

Introduction:

Blood and Pain system is a battle engine core based on a two layer defense::
-Pain damage;
-Blood damage;

— Parameters Involved:

-Strenght: it affects both pain and blood damage;
-Atk: it affects both pain and blood damage;

-Dexterity: it affects evasion;
-Speed: it affects action speed;

-Pain Defense (physical defense): reduces pain damage;
-Blood Defense (spell defense): reduces blood damage;

-Evasion: rate of hit evasion;

-Blood: real HP stat. Once they run out, the battler dies.
-Pain: ex-SP. Second main stat. if Pain Bar is full, battler cannot move.

-Intelligence is not considered.

NOTE: Base EVA for all enemies has to be AT LEAST 60. If not, they would be
[DEADLY] hit by every attack.

NOTE: Atk has to be at least 100... damage calculation is A LOT DIFFERENT from the base engine...

— Battle algorithms

Pain affects speed and precision of any battler.

Ordinary attacks deal both Pain and Blood damage. Blood damage is dealt only
when pain level is too high.

Skills are divided in [PAIN SKILLS] and [BLOOD SKILLS].
They can do only one kind of damage;

Guard halves [PAIN DAMAGE] and nullifies [BLOOD DAMAGE];

[DEADLY]
A deadly blow is carried when target is almost motionless (high pain level);
it results in a 1.5 x damage and haemoraggie status activation;

[GUARD BREAK]
Guard is not activated until "Guard" word shows.
if a battler is hit before, he/her lose turn and take a 1.5 x damage;

[BRUTAL BREAK]
If a deadly blow is delivered with a guard break, it becomes a [BRUTAL BREAK]
(3 x damage, Haemoraggie)

If all party memebers have full pain, or are dead, or fainted, is game_over!

— How to subdivide skills

Skill:

-sp cost SHOULD BE 0. Otherwise, Pain will be decreased if a skil is used.

-dex_f becomes the damage multiplier. ex. 25 means damage will be multiplied
by 2.5

-str_f indicates [PAIN DAMAGE]. if both int_f and str_f are different from 0,
Pain has priority.
*** Only pain skills must have this parameter different from 0 ***

-int_f indicates [BLOOD DAMAGE]
*** Only blood skills must have this parameter different from 0 ***

-phy def force and mag def force are not employed in here.

-agi_f indicates priority. For example, Guard has priority 50. If a skill has agi_f greater than 50, Guard Break can occur.

-Examples:

Skill:
Short Knife;
Str F = 100;
Atk = 100;
Power = 5;

A pain skill that affects pain defence.

Skill:
Heavy Blow
Int F = 100;
Atk = 100;
Power = 5;

A blood skill that affects blood defence.

— Painkiller items:
# It affects certain items and make thier effect vanish into a certain
# number of turns [num]. For example, Weak Painkiller reduces Pain by 500.
# On the fourth turn after the use, 50 Pain is added to actor's Pain,
# on the fifth turn 100 Pain and so on...
# General flow chart:
# -Item use, target's pain -= EFF;
# -[num] turns without countereffects;
# -turn [num+1]: target's pain += 10% EFF;
# -turn [num+2]: target's pain += 20% EFF;
# -turn [num+3]: target's pain += 30% EFF;
# -turn [num+4]: target's pain += 40% EFF;
# -TOTAL: 100%
# Painkillers reduce pain's PERCEPTION, so it's natural that after a certain
# time, effects will begin to fade.

-How to:

To make a painkiller item, just put their variance equal to the effect turn number
[num].
Pain damage can be cured with SP depletion (actually, you have to lower sp value));

Example:
Item: Weak Painkiller
SP Recovery = -500;
Variance = 3;

Effect:
-Item use, target's pain -= 500;
# -2 turns without countereffects;
# -turn [3]: target's pain += 50;
# -turn [4]: target's pain += 100;
# -turn [5]: target's pain += 150;
# -turn [6]: target's pain += 200;
# -TOTAL: 100%

NOTE: if variance is set to 0, item WILL NOT BE a Painkiller and its effect
won't expire.

NOTE: you can create blood cure item:: just use the recover HP parameter;

NOTE: you can even cure Haemoraggie and Faint: just set to "-" the checked box
on status modifications.


— Status:

- Haemoraggie:

Like poison, it causes gradual damage;
can be cured with an item that removes [HAEMO STATUS].

- Faint:

Battler cannot act;
can be cured with an item that removes [FAINT STATUS].


- Death:

Battler is currently dead;
cannot be cured in battle.

— Constants:
Please remember to SET THE RIGHT CONSTANTS in the first script section
EDIT IT AS YOU NEED!

@hud_switch = 2 #Switch that triggers map turns for painkillers

@seconds_per_turn = 60.0 #Seconds per map turn

@haemorragie_state_id = 3 #[HAEMO STATUS] id

@faint_state_id = 2 #[FAINT STATUS] id

@death_state_id = 1 #[DEATH STATUS] id

NOTE: Damage font is set to "Viner Hand ITC" If you haven't it, modify it in the
RPG::Sprite script

#-------------------------------------------------------------------------------


Create a new script and paste this into:

Script Part 1
#=========================================================================
=====
# �€“� Pain & Blood system
#------------------------------------------------------------------------------
# created by Jens of Zanicuud. V 0.7
# please give credit if used.
# you can find me in www.rpgrevolution.com
# if you use it, please tell me, so that I can see my work in action
# Thanks!
#==============================================================================

#--------------------------------------------------------------------------
# �€”� Constants
# A class that handles with constants
#--------------------------------------------------------------------------
class Constants
attr_reader :hud_switch
attr_reader :seconds_per_turn
attr_reader :chain_sprite
attr_reader :haemorragie_state_id
attr_reader :faint_state_id
attr_reader :death_state_id

def initialize
#battle_mugs( Hash: {actor_id => face_name (it has to be a picture)} )
@battle_mugs = {
1 => "Eric_Mug_2",
2 => "Laese_Mug",
}
@blood_types = {
1 => "AB",#Eric
2 => "0",#Laese
3 => "A",#Cybil
4 => "AB",#Edvard
5 => "A",#Remo
6 => "B",#Eri
7 => "A",#Renzo
}
@blood_rh ={
1 => "-",#Eric
2 => "+",#Laese
3 => "+",#Cybil
4 => "+",#Edvard
5 => "+",#Remo
6 => "+",#Eri
7 => "-",#Renzo
}
#hud switch
@hud_switch = 2
#map seconds per turn
@seconds_per_turn = 60.0
#chain sprite
@chain_sprite = "chain"
#blood loss status
@haemorragie_state_id = 3
@faint_state_id = 2
@death_state_id = 1
end
#--------------------------------------------------------------------------
# �€”� Faces in battle
#--------------------------------------------------------------------------
def battle_mug(id)
return @battle_mugs[id]
end
#--------------------------------------------------------------------------
# �€”� Blood Types
#--------------------------------------------------------------------------
def blood_types(id)
return @blood_types[id]
end
#--------------------------------------------------------------------------
# �€”� Blood Rhs
#--------------------------------------------------------------------------
def blood_rh(id)
return @blood_rh[id]
end
#--------------------------------------------------------------------------
# �€”� Load Faces bitmap
# Hash: {actor_id => face_name (has to be a picture)}
#--------------------------------------------------------------------------
def load_battle_mug(id)
return RPG::Cache.picture(@battle_mugs[id])
end
#--------------------------------------------------------------------------
# �€”� Load Chain Sprite
#--------------------------------------------------------------------------
def load_chain_sprite
return RPG::Cache.picture(@chain_sprite)
end
end

#--------------------------------------------------------------------------
# �€”� Game_Actor (Blood type and Rh system)
#--------------------------------------------------------------------------
class Game_Actor < Game_Battler
attr_reader :blood_t
attr_reader :blood_rh

#setup

alias startup setup
def setup(actor_id)
startup(actor_id)
@blood_t = $game_system.data.blood_types(actor_id)
@blood_rh = $game_system.data.blood_rh(actor_id)
@painkiller_turns = {}
@addiction = 0
for i in 0...20
@painkiller_turns[i] = 0
end
self.sp = 0 #pain reset
end

#blood_type_print

def p_blood_t
return (@blood_t+"_blood")
end

#blood_rh_print

def p_blood_rh
case @blood_rh
when "+"
return "rh_blood"
when "-"
return "no_rh_blood"
end
end

#blood_change
def blood_change(type,rh)
case type
when 0
@blood_t = "0"
when 1
@blood_t = "A"
when 2
@blood_t = "B"
when 3
@blood_t = "AB"
end

case rh
when 0
@blood_rh = "-"
when 1
@blood_rh = "+"
end

end

#can_receive_from?
def can_receive_from?(actor)
if actor.blood_rh != self.blood_rh
return false
end
if self.blood_t == "0" and actor.blood_t != "0"
return false
end
if self.blood_t == "A" and (actor.blood_t == "B" or actor.blood_t == "AB")
return false
end
if self.blood_t == "B" and (actor.blood_t == "A" or actor.blood_t == "AB")
return false
end
if actor.blood_t == "0"
return true
end
if self.blood_t == "AB"
return true
end
return true
end

#can_donate?
def can_donate?(actor)
return actor.can_receive_from?(self)
end


#addiction_check
def addicted?
return @addiction > 30
end

#addiction
def addiction
return @addiction
end

#painkiller_effect
def painkiller_effect(item)
painkiller_effect = (item.recover_sp).abs
pain_recoverd = [self.sp,painkiller_effect].min
pain_turn = [(item.variance-(self.addiction/10)),0].max
for i in 1...5
@painkiller_turns[pain_turn+i] += pain_recoverd*(i*10)/100
end
if @painkiller_turns[0] != 0
@addiction += 1
end
end

#painkiller_vanishing_turn_check
def painkiller_vanishing_turn_check
for i in 0...@painkiller_turns.keys.size-1
@painkiller_turns[i] = @painkiller_turns[i+1]
end
@painkiller_turns[@painkiller_turns.keys.size-1] = 0
self.sp += @painkiller_turns[0]
end

#recover_all
def recover_all
super
@sp = 0
painkiller_restart
end

#painkiller_restart
def painkiller_restart
for i in 0...@painkiller_turns.keys.size
@painkiller_turns[i] = 0
end
end

#pain_status
def pain_status
return self.sp >= self.maxsp
end

#chance of being prevented from attacking due to a high pain level
def pain_stop_motion_chance
chance = Math::exp(-(6*(self.maxsp-self.sp)/self.maxsp.to_f)**2)
chance *= 10000.0
chance = chance.to_i
if chance > rand(10000)
return true
end
return false
end

#inputable?
def inputable?
return (not @hidden and restriction <= 1 and !self.pain_status)
end
end

#--------------------------------------------------------------------------
# *** Painkiller system (only with Blood System)***
# It affects certain items and make thier effect vanish into a certain
# number of turns [num]. For example, Weak Painkiller reduces Pain by 500.
# On the fourth turn after the use, 50 Pain is added to actor's Pain,
# on the fifth turn 100 Pain and so on...
# General flow chart:
# -Item use, target's pain -= EFF;
# -[num] turns without countereffects;
# -turn [num+1]: target's pain += 10% EFF;
# -turn [num+2]: target's pain += 20% EFF;
# -turn [num+3]: target's pain += 30% EFF;
# -turn [num+4]: target's pain += 40% EFF;
# -TOTAL: 100%
# Painkillers reduce pain's PERCEPTION, so it's natural that after a certain
# time, effects will begin to fade.
# To make a Painkiller, just set item variance as the number of turns you have
# before effect vanish...
#--------------------------------------------------------------------------

class RPG::Item
#definition of painkiller_item
def is_a_painkiller?
return self.recover_sp < 0
end
end

class Game_Battler
#--------------------------------------------------------------------------
# �€”� B-system painkillers
# item : �€š��€š��’€�’�
#--------------------------------------------------------------------------
alias b_system_item_effect item_effect
def item_effect(item)
if item.is_a_painkiller?
self.painkiller_effect(item)
end
effective = b_system_item_effect(item)
return effective
end
end

#--------------------------------------------------------------------------
# *** Scene Battle Modifications
#--------------------------------------------------------------------------
class Scene_Battle
#--------------------------------------------------------------------------
# �€”� start_phase2_begin
#--------------------------------------------------------------------------
def start_phase2_begin
# �’€�€š��’��€š� 2 に移��’
@phase = 2
# �€š��€š��€š��’��€š€™��ž選�Šž�Š��€€
設��š
@actor_index = -1
@active_battler = nil
# �’€˜�’��’€�€š��€š��’ž�’��’€�€š��€š
��’��’€�€š��€š€™�“€�Š��’€“
@party_command_window.active = true
@party_command_window.visible = true
# �€š��€š��€š��’��€š��’ž�’��’€�€š��
€š��’��’€�€š��€š€™�€ž��Š��’€“
@actor_command_window.active = false
@actor_command_window.visible = false
# �’��€š��’��’€�€š��’��€š��’€�’��€
š��€š€™�€š��’��€š�
$game_temp.battle_main_phase = false
# �’€˜�’��’€�€š��€��€œ�の�€š��€š��€š
�’��’��€š€™�€š��’��€š�
$game_party.clear_actions
# �€š��’ž�’��’€�€��Š€不可�’�な場��†
end
#--------------------------------------------------------------------------
# �€”� start_phase2
#--------------------------------------------------------------------------
def start_phase2
start_phase2_begin
#painkiller_turn_check for every party_member
for actor in $game_party.actors
actor.painkiller_vanishing_turn_check
end
unless $game_party.inputable?
start_phase4
end
end

end

class Scene_Battle
#--------------------------------------------------------------------------
# �€”� Judge (added faint condition)
#--------------------------------------------------------------------------
def judge
# �€���€�†���š��’�“Ÿ�‚�ま��Ÿは�’€˜
�’��’€�€š�人�€���’ 0 人の場��†
if $game_party.all_dead? or $game_party.actors.size == 0 or
$game_party.all_fainted?
# �€€”�’€”可�’�の場��†
if $game_temp.battle_can_lose
# �’��’†�’��€“€��€�€�の BGM に�†���„
$game_system.bgm_play($game_temp.map_bgm)
# �’��’†�’���€š��€
battle_end(2)
# true �€š€™��€��„
return true
end
# �€š��’��’��€š��’��’��’��’€�’��€š
��€š€™�€š��’’�’†
$game_temp.gameover = true
# true �€š€™��€��„
return true
end
# �€š��’��’Ÿ�’���’ 1 ��€œで�€š€š��œ�“���„�€š’ば false �€š€™��€��„
for enemy in $game_troop.enemies
if enemy.exist?
return false
end
end

if $game_troop.all_fainted?
return true
end
# �€š��’€�€š��’��’��’†�’��’€�€š��’
�€š��€“€��€ (�€��†�)
start_phase5
# true �€š€™��€��„
return true
end
#------------
#--------------------------------------------------------------------------
# �€”� battler cannot act if his or her pain level is too high
#--------------------------------------------------------------------------
alias b_system_make_basic_action_result make_basic_action_result
def make_basic_action_result
b_system_make_basic_action_result
#if @active_battler.current_action.basic == 4
#name = @active_battler.name
#@help_window.set_text("Pain prevented "+name+" from acting!", 1)
#$game_temp.message_text = "Pain prevented "+name+" from acting!"
#return
#end
end
#--------------------------------------------------------------------------
# �€”� update_phase4_step2
#--------------------------------------------------------------------------
alias b_system_update_phase4_step2 update_phase4_step2
def update_phase4_step2
#if @active_battler.is_a?(Game_Actor)
if @active_battler.pain_stop_motion_chance
@active_battler.current_action.basic = 4
@active_battler.current_action.kind = 0
end
#end
b_system_update_phase4_step2
end
#--------------------------------------------------------------------------
# �€”� update_phase4_step3
#--------------------------------------------------------------------------
alias b_system_update_phase4_step3 update_phase4_step3
def update_phase4_step3
b_system_update_phase4_step3
if @active_battler.current_action.basic == 4
name = @active_battler.name
$game_temp.message_text = "Pain prevented "+name+" from acting!"
return
end
end
#--------------------------------------------------------------------------
# �€”� update_phase4_step5
#--------------------------------------------------------------------------
alias b_system_update_phase4_step5 update_phase4_step5
def update_phase4_step5
for target in @target_battlers
if target.current_action.basic == 5
name = target.name
$game_temp.message_text = name+" fainted!"
target.current_action.clear
return
end
end
b_system_update_phase4_step5
end
end

#==============================================================================
# �€“� Game_System
#------------------------------------------------------------------------------
# added time register for map turns
#==============================================================================

class Game_System
attr_accessor :after_battle_time
attr_accessor :data
alias b_system_initialize initialize
def initialize
b_system_initialize
@after_battle_time = Time.now
@data = Constants.new
end
end

#==============================================================================
# �€“� Scene_Battle
#------------------------------------------------------------------------------
# adds time_stamp after battle_ending
#==============================================================================

class Scene_Battle
alias b_system_battle_end battle_end
def battle_end(result)
b_system_battle_end(result)
$game_system.after_battle_time = Time.now
end
end
#==============================================================================
# �€“� Game_Map
#------------------------------------------------------------------------------
# added painkiller routine to the map. A "turn" is considered a certain amount
# of time.
#==============================================================================

class Game_Map
alias b_system_update update
def update
b_system_update
#pain can rise only if the game is played (that is no cutscene)
if $game_switches[$game_system.data.hud_switch]
#pain rising every NUM seconds
if (Time.now-$game_system.after_battle_time) >= $game_system.data.seconds_per_turn
$game_system.after_battle_time = Time.now
for actor in $game_party.actors
actor.painkiller_vanishing_turn_check
end
end
end
end
end

#==============================================================================
# �€“� Battle Algorithms
#------------------------------------------------------------------------------
# The battle engine core: damage algorithm and stuff like this
#==============================================================================

class Game_Temp
attr_accessor:message_text_b
end

class Game_Party
#--------------------------------------------------------------------------
# �€”� clear_actions (remove also guard)
#--------------------------------------------------------------------------
def clear_actions
for actor in self.actors
actor.current_action.clear
actor.guard_remove
end
end
#--------------------------------------------------------------------------
# �€”� all_fainted?
#--------------------------------------------------------------------------
def all_fainted?
flag = true
for actor in self.actors
if !(actor.state?($game_system.data.faint_state_id) or actor.pain_status)
flag = false
end
end
return flag
end
end

class Game_Troop
#--------------------------------------------------------------------------
# �€”� all_fainted?
#--------------------------------------------------------------------------
def all_fainted?
flag = true
for actor in self.enemies
if !(actor.state?($game_system.data.faint_state_id) or actor.pain_status)
flag = false
end
end
return flag
end
end

class Game_Enemy < Game_Battler
#--------------------------------------------------------------------------
# �€”� initialize (pain = 0)
#--------------------------------------------------------------------------
alias b_system_enemy_initialize initialize
def initialize(troop_id, member_index)
b_system_enemy_initialize(troop_id, member_index)
self.sp = 0
end
#--------------------------------------------------------------------------
# �€”� make_action (guard_remove)
#--------------------------------------------------------------------------
alias b_system_make_action make_action
def make_action
self.guard_remove
b_system_make_action
end
#--------------------------------------------------------------------------
# �€”� pain_stop_motion_chance
# chance of being prevented from attacking due to a high pain level
#--------------------------------------------------------------------------
def pain_stop_motion_chance
chance = Math::exp(-(6*(self.maxsp-self.sp)/self.maxsp.to_f)**2)
chance *= 10000.0
chance = chance.to_i
if chance > rand(10000)
return true
end
return false
end
end

class Game_Actor < Game_Battler
#--------------------------------------------------------------------------
# �€”� �Ÿ��“��€ž避修正の��€“��€”
#--------------------------------------------------------------------------
alias b_system_base_eva base_eva
def base_eva
return b_system_base_eva + 75
end
end

#==============================================================================
# �€“� Game_Battler
#------------------------------------------------------------------------------
# update: pain & hp damage, action speed correction, stats modifications,
# different battle algorithms, haemoraggie added
#==============================================================================
class Game_Battler
attr_accessor :b_damage
attr_accessor :guard_break
#--------------------------------------------------------------------------
# �€”� initialize (added variable guarding)
#--------------------------------------------------------------------------
alias b_system_initialize initialize
def initialize
b_system_initialize
@guarding = false
@b_damage = nil
@guard_break = false
end
#--------------------------------------------------------------------------
# �€”� make_action_speed (guard has the highest priority)
#--------------------------------------------------------------------------
def make_action_speed
@current_action.speed = agi + rand(10 + agi / 4)
if @current_action.kind == 0 and @current_action.basic == 1
@current_action.speed += 50
end
if @current_action.kind == 1 #updating speed for skill
skill_id = @current_action.skill_id
skill = $data_skills[skill_id]
@current_action.speed += skill.agi_f
end
end
#--------------------------------------------------------------------------
# �€”� guarding?
#--------------------------------------------------------------------------
def guarding?
return @guarding
end
#--------------------------------------------------------------------------
# �€”� bloodloss?
#--------------------------------------------------------------------------
def bloodloss?
return self.state?($game_system.data.haemorragie_state_id)
end
#--------------------------------------------------------------------------
# �€”� guard_remove
#--------------------------------------------------------------------------
def guard_remove
@guarding = false
end
#--------------------------------------------------------------------------
# �€”� activate_guard
#--------------------------------------------------------------------------
def activate_guard
@guarding = true
end
#--------------------------------------------------------------------------
# �€”� strength (corrected by pain level)
#--------------------------------------------------------------------------
alias b_system_str str
def str
n = b_system_str*(1-self.sp/(5*self.maxsp).to_f)
return n
end
#--------------------------------------------------------------------------
# �€”� dexterity (corrected by pain level)
#--------------------------------------------------------------------------
alias b_system_dex dex
def dex
n = b_system_dex*(1-self.sp/(3*self.maxsp).to_f)
return n
end
#--------------------------------------------------------------------------
# �€”� agility (corrected by pain)
#--------------------------------------------------------------------------
alias b_system_agi agi
def agi
n = b_system_agi*(1-self.sp/(3*self.maxsp).to_f)
return n
end
#--------------------------------------------------------------------------
# �€”� intelligence (?) (corrected by pain)
# I'm not planning to employ this stat...
#--------------------------------------------------------------------------
alias b_system_int int
def int
n = b_system_int
return n
end
#--------------------------------------------------------------------------
# �€”� evasion (corrected by pain)
# I think I will improve this... modulated by a gaussian-like distribution
#--------------------------------------------------------------------------
alias b_system_eva eva
def eva
n = b_system_eva*Math::exp(-2*(self.sp/self.maxsp.to_f)**2)
return n.to_i
end
#--------------------------------------------------------------------------
# �€”� accuracy
#--------------------------------------------------------------------------
def accuracy
#accuracy will range from 22.5 to 75
return ((self.dex*100/self.base_dex)*0.75)
end
#--------------------------------------------------------------------------
# �€”� slip damage effect (why poison? Haemoraggie is the answer!)
#--------------------------------------------------------------------------
def slip_damage?
if self.bloodloss?
return true
end
for i in @states
if $data_states[i].slip_damage
return true
end
end
return false
end
#--------------------------------------------------------------------------
# �€”� slip damage effect... 1/10 is too much, let's set 1/30
#--------------------------------------------------------------------------
def slip_damage_effect
# �’‚�’��’��€š��€š€™設��š
self.b_damage = self.maxhp / 30
# �†€�€�
if self.b_damage.abs > 0
amp = [self.b_damage.abs * 15 / 100, 1].max
self.b_damage += rand(amp+1) + rand(amp+1) - amp
end
# HP ��€�€š€�’‚�’��’��€š��€š€™��€��€”
self.hp -= self.b_damage
self.damage = ""
# �’��€š��’’�’€��€š��€
return true
end
#--------------------------------------------------------------------------
# �€”� melee attack battle algorithm
# attacker : attacking battler
#--------------------------------------------------------------------------
def attack_effect(attacker)
#hit result: depends on self speed and evasion and attacker accuracy
#it's usually lesser than 75
hit_result = false
#weak factor: if hit rate is low, but not inexhistent the attack can be
#landed with a tiny amount of damage
weakening = false
#hit is decided by a random 20% factor
hit = attacker.accuracy+rand(attacker.accuracy/5)
#if evasion is greater than hit, attack misses
@guard_break = false
if hit > self.eva
hit_result = true
end
hit_rate = hit-self.eva
#see notes about weakining...
if !hit_result and hit_rate > -8
hit_result = true
weakening = true
end
if hit_result
hp_damage = 0
sp_damage = 0
#calculating pain damage
sp_damage = (attacker.atk+attacker.str)-self.pdef
sp_damage += rand(sp_damage/10)
#weak attack correction
if weakening
sp_damage *= (8-(hit_rate).abs)/8
end
#if target is almost motionless, hp damage is possible (i.e. blood loss)
#if target is going to guard when hit... guard break!
if self.current_action.basic == 1 and self.current_action.kind = 0 and
not self.guarding?
@guard_break = true
self.guard_remove
self.current_action.clear
hp_damage *= 1.5
end
if self.guarding?
#guard prevents hp damage
sp_damage /= 2
hp_damage = 0
elsif !weakening
#if pain level is to high, target can faint and not able to attack
if self.sp >= 0.75*self.maxsp and sp_damage > 0
if rand(self.sp) > self.maxsp*0.75 and !self.state?($game_system.data.faint_state_id)
self.add_state($game_system.data.faint_state_id)
self.current_action.clear
self.current_action.kind = 0
self.current_action.basic = 5
end
end
if 40+rand(10) < hit_rate
#calculating hp damage
hp_damage = (attacker.atk+attacker.str)-self.mdef
hp_damage += rand(hp_damage/10)
end
#if target is extremely motionless, haemorragie is possible (i.e. blood loss)
if 60+rand(10) < hit_rate
self.add_state($game_system.data.haemorragie_state_id)
self.critical = true
hp_damage *= 1.5
end
end
#damaging target
self.hp -= [hp_damage.to_i,0].max
self.sp += [sp_damage.to_i,0].max
self.damage = sp_damage.to_i
if hp_damage == 0
self.b_damage = nil
else
self.b_damage = hp_damage.to_i
end
else
#if hit result is false, damage is set to "Miss"
self.damage = "Miss"
self.critical = false
end
end
#--------------------------------------------------------------------------
# �€”� skills algorithm
#--------------------------------------------------------------------------
def skill_effect(user, skill)
#critical flag reset
self.critical = false
# scope correction
if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or
((skill.scope == 5 or skill.scope == 6) and self.hp >= 1)
# if the scope is wrong, skill isn't cast
return false
end
#effective flag reset
effective = false
#effective true if skill has a common_event
effective |= skill.common_event_id > 0
#user's accuracy
accuracy_rating = user.accuracy+rand(user.accuracy/5)
#hit rate calculation: if power is greater than 0, hit rate is reduced
if skill.power > 0
hit = (skill.hit*accuracy_rating)/100
else
hit = skill.hit
end
#hit calculation: if accuracy is lesser than evasion, the skill misses
hit_rate = hit-self.eva
hit_result = (hit_rate > 0)
if hit_result
#status change check
@state_changed = false
effective |= states_plus(skill.plus_state_set)
effective |= states_minus(skill.minus_state_set)
#and now, damage effect:
#str_force: pain attack
#int_force: hp attack
power = skill.power
#calculating pain damage
if skill.str_f != 0 and skill.int_f == 0
power += (skill.str_f*user.str)/100
power += (skill.atk_f*user.atk)/100
power += (2*rand(power.to_i*skill.variance/100) - power*skill.variance/100)
power -= (self.pdef)
#dex_f becomes the multiplier
if power > 0
power *= (skill.dex_f/10)
end
sp_damage = power
@guard_break = false
#guard reduces damage as ever... but not if target has to guard yet!
if self.current_action.basic == 1 and self.current_action.kind = 0 and
not self.guarding?
@guard_break = true
self.guard_remove
self.current_action.clear
end
#if target is not guarding and pain level's too high... he/her faints.
if self.guarding?
sp_damage /= 2
else
if self.sp >= 0.75*self.maxsp and sp_damage > 0
if rand(self.sp) > self.maxsp*0.75 and !self.state?($game_system.data.faint_state_id)
self.add_state($game_system.data.faint_state_id)
self.current_action.clear
self.current_action.kind = 0
self.current_action.basic = 5
end
end
end
self.damage = [sp_damage.to_i,0].max
self.b_damage = ""
self.sp += self.damage
end
#calculating blood damage
if skill.str_f == 0 and skill.int_f != 0
power += (skill.int_f*user.str)/100
power += (skill.atk_f*user.atk)/100
power += (2*rand(power.to_i*skill.variance/100) - power*skill.variance/100)
power -= (self.mdef)
#dex_f become the multiplier
if power > 0
power *= (skill.dex_f/10)
end
hp_damage = power
@guard_break = false
#guard nullifies hp_damage... but not if target has to guard yet...
#else... damage doubled!
if self.current_action.basic == 1 and self.current_action.kind = 0 and
not self.guarding?
@guard_break = true
self.guard_remove
self.current_action.clear
hp_damage *= 2
end
if self.guarding?
hp_damage = 0
self.b_damage = "Guard!"
return false
else
if 60+rand(10) < hit_rate
self.add_state($game_system.data.haemorragie_state_id)
self.critical = true
hp_damage *= 1.5
end
self.damage = ""
self.b_damage = [hp_damage.to_i,0].max
self.hp -= self.b_damage
end
end
else
self.damage = "Miss"
self.critical = false
end
return effective
end

end


Then, you'll need to paste this in order to view the correct damage pop...
Create a new script and paste this into:

Damage visualization
class RPG::Sprite

def dispose_damage
if @_damage_sprite != nil
@_damage_sprite.bitmap.dispose
@_damage_sprite.dispose
@_damage_sprite = nil
@_damage_duration = 0
end
if @_damage_sprite2 != nil
@_damage_sprite2.bitmap.dispose
@_damage_sprite2.dispose
@_damage_sprite2 = nil
@_damage_duration2 = 0
end
end

def damage(value, b_value, critical,guard_break)
dispose_damage
if value.is_a?(Numeric)
damage_string = value.abs.to_s
else
damage_string = value.to_s
end
bitmap = Bitmap.new(160, 48)
bitmap.font.name = "Viner Hand ITC"
bitmap.font.size = 45
bitmap.font.color.set(0, 0, 0)
bitmap.draw_text(-1, 12-1, 160, 36, damage_string, 1)
bitmap.draw_text(+1, 12-1, 160, 36, damage_string, 1)
bitmap.draw_text(-1, 12+1, 160, 36, damage_string, 1)
bitmap.draw_text(+1, 12+1, 160, 36, damage_string, 1)
if value.is_a?(Numeric) and value > 0
bitmap.font.color.set(230, 190, 20)
elsif value.is_a?(Numeric)
bitmap.font.color.set(176, 255, 144)
else
bitmap.font.color.set(210, 210, 210)
end
bitmap.draw_text(0, 12, 160, 36, damage_string, 1)
@_damage_sprite = ::Sprite.new(self.viewport)
@_damage_sprite.bitmap = bitmap
@_damage_sprite.ox = 80
@_damage_sprite.oy = 20
@_damage_sprite.x = self.x
@_damage_sprite.y = self.y - self.oy / 2
@_damage_sprite.z = 3000
@_damage_duration = 40

if b_value.is_a?(Numeric)
damage_string = b_value.abs.to_s
else
damage_string = b_value.to_s
end
bitmap = Bitmap.new(160, 48)
bitmap.font.name = "Viner Hand ITC"
bitmap.font.size = 45
bitmap.font.color.set(0, 0, 0)
bitmap.draw_text(-1, 16-1, 160, 36, damage_string, 1)
bitmap.draw_text(+1, 16-1, 160, 36, damage_string, 1)
bitmap.draw_text(-1, 16+1, 160, 36, damage_string, 1)
bitmap.draw_text(+1, 16+1, 160, 36, damage_string, 1)
if b_value.is_a?(Numeric) and b_value < 0
bitmap.font.color.set(255, 255, 255)
else
bitmap.font.color.set(255, 80, 0)
end
bitmap.draw_text(0, 16, 160, 36, damage_string, 1)

if not (critical and guard_break)

if critical
bitmap.font.size = 24
bitmap.font.color.set(0, 0, 0)
bitmap.draw_text(-1, -1+6, 160, 20, "DEADLY!", 1)
bitmap.draw_text(+1, -1+6, 160, 20, "DEADLY!", 1)
bitmap.draw_text(-1, +1+6, 160, 20, "DEADLY!", 1)
bitmap.draw_text(+1, +1+6, 160, 20, "DEADLY!", 1)
bitmap.font.color.set(255, 80, 0)
bitmap.draw_text(0, 6, 160, 20, "DEADLY!", 1)
end
if guard_break
bitmap.font.size = 24
bitmap.font.color.set(0, 0, 0)
bitmap.draw_text(-1-20, -1+6, 200, 20, "GUARD BREAK!", 1)
bitmap.draw_text(+1-20, -1+6, 200, 20, "GUARD BREAK!", 1)
bitmap.draw_text(-1-20, +1+6, 200, 20, "GUARD BREAK!", 1)
bitmap.draw_text(+1-20, +1+6, 200, 20, "GUARD BREAK!", 1)
bitmap.font.color.set(255, 80, 0)
bitmap.draw_text(-20, 6, 200, 20, "GUARD BREAK!", 1)
end

else
bitmap.font.size = 24
bitmap.font.color.set(0, 0, 0)
bitmap.draw_text(-1-20, -1+6, 200, 20, "BRUTAL BREAK!", 1)
bitmap.draw_text(+1-20, -1+6, 200, 20, "BRUTAL BREAK!", 1)
bitmap.draw_text(-1-20, +1+6, 200, 20, "BRUTAL BREAK!", 1)
bitmap.draw_text(+1-20, +1+6, 200, 20, "BRUTAL BREAK!", 1)
bitmap.font.color.set(255, 80, 0)
bitmap.draw_text(-20, 6, 200, 20, "BRUTAL BREAK!", 1)
end
@_damage_sprite2 = ::Sprite.new(self.viewport)
@_damage_sprite2.bitmap = bitmap
@_damage_sprite2.ox = 80
@_damage_sprite2.oy = 20
@_damage_sprite2.x = self.x
@_damage_sprite2.y = self.y - self.oy / 2 + 35
@_damage_sprite2.z = 3000
@_damage_duration2 = 40
end

def update
super
if @_whiten_duration > 0
@_whiten_duration -= 1
self.color.alpha = 128 - (16 - @_whiten_duration) * 10
end
if @_appear_duration > 0
@_appear_duration -= 1
self.opacity = (16 - @_appear_duration) * 16
end
if @_escape_duration > 0
@_escape_duration -= 1
self.opacity = 256 - (32 - @_escape_duration) * 10
end
if @_collapse_duration > 0
@_collapse_duration -= 1
self.opacity = 256 - (48 - @_collapse_duration) * 6
end
if @_damage_duration > 0
@_damage_duration -= 1
@_damage_duration2 -= 1
case @_damage_duration
when 38..39
@_damage_sprite.y -= 4
@_damage_sprite2.y -= 4
when 36..37
@_damage_sprite.y -= 2
@_damage_sprite2.y -= 2
when 34..35
@_damage_sprite.y += 2
@_damage_sprite2.y += 2
when 28..33
@_damage_sprite.y += 4
@_damage_sprite2.y += 4
end
@_damage_sprite.opacity = 256 - (12 - @_damage_duration) * 32
@_damage_sprite2.opacity = 256 - (12 - @_damage_duration2) * 32
if @_damage_duration == 0 and @_damage_duration2 == 0
dispose_damage
end
end
if @_animation != nil and (Graphics.frame_count % 2 == 0)
@_animation_duration -= 1
update_animation
end
if @_loop_animation != nil and (Graphics.frame_count % 2 == 0)
update_loop_animation
@_loop_animation_index += 1
@_loop_animation_index %= @_loop_animation.frame_max
end
if @_blink
@_blink_count = (@_blink_count + 1) % 32
if @_blink_count < 16
alpha = (16 - @_blink_count) * 6
else
alpha = (@_blink_count - 16) * 6
end
self.color.set(255, 255, 255, alpha)
end
@@_animations.clear
end


end



In the end, open Sprite_Battler and replace:

if @battler.damage_pop
damage(@battler.damage, @battler.critical,)
@battler.damage = nil
@battler.critical = false
@battler.damage_pop = false
end

with

Sprite_Battler: line 109
if @battler.damage_pop
damage(@battler.damage, @battler.b_damage, @battler.critical,@battler.guard_break)
@battler.damage = nil
@battler.b_damage = nil
@battler.critical = false
@battler.damage_pop = false
@battler.guard_break = false
end


Ok, this should work...
Ask me for troubleshooting everytime.

Jens

This post has been edited by Jens of Zanicuud: Dec 10 2011, 02:12 AM


__________________________
"Thorns are the rose's sweetest essence..."
-Jens of Zanicuud


Games I'm working on:
>

official website: TryAdIne eFfeCt

>

Games I worked on (mainly as a scripter):
>
(Warning: it's a 3rr3's project and it's in Italian!)


Awards

Go to the top of the page
 
+Quote Post
   
Night_Runner
post Dec 6 2011, 03:56 PM
Post #2


Level 50
Group Icon

Group: +Gold Member
Posts: 1,528
Type: Scripter
RM Skill: Undisclosed




For people wondering, it is still a front view battle system, exactly like the default, except it's using the Blood & Pain engine do calculate SP & damage, it actually looks quite aggressive
Image


Check out the link Jens' original topic to see the full feature list (link).

And for those who just want to test it out, or aren't comfortable with scripting, I've uploaded a demo for you guys
link
As Jens said, there's the two scripts at the end that you need, and the script I've renames ** Sprite_Battler instead of Sprite_Battler so you can find it easier, and you'll need all 3 scripts for it to work.



Thanks Jens, it looks really impressive smile.gif


__________________________
K.I.S.S.
Want help with your scripting problems? Upload a demo! Or at the very least; provide links to the scripts in question.

Most important guide ever: Newbie's Guide to Switches
Go to the top of the page
 
+Quote Post
   
SleepingSirenx
post Dec 7 2011, 03:12 AM
Post #3


The SMT Maniac
Group Icon

Group: Revolutionary
Posts: 125
Type: Developer
RM Skill: Undisclosed




When the battle ends, I get an error saying :


Script 'Blood & Pain - Battle Sys' line 519: No Method Error occured.
undefined method `actors' for # <Game_Troop:0x160cc98>

On the other hand. The battle system's good. Another template than the standard "HP"&"SP" figures.
Well then, goodluck.

This post has been edited by SleepingSirenx: Dec 7 2011, 03:21 AM


__________________________

My First Game .... Yeah .... ~♥
I'm In Need Of A Team To Help Me WIth The Development Of My Game PM Me. :)
- DEMO's On Progress!

I Support This Projects!



Please Teach Me How To Script. :(
I'm Learning How To Script. But Still Teach Me How To Script :)
Damn THERMODYNAMICS! Makes My Head Spin!
Go to the top of the page
 
+Quote Post
   
Jens of Zanicuud
post Dec 8 2011, 03:00 AM
Post #4


Dark Jentleman
Group Icon

Group: Local Mod
Posts: 904
Type: Scripter
RM Skill: Skilled
Rev Points: 120




QUOTE (SleepingSirenx @ Dec 7 2011, 12:12 PM) *
When the battle ends, I get an error saying :


Script 'Blood & Pain - Battle Sys' line 519: No Method Error occured.
undefined method `actors' for # <Game_Troop:0x160cc98>

On the other hand. The battle system's good. Another template than the standard "HP"&"SP" figures.
Well then, goodluck.


I think you can fix it by replacing "actors" with "enemies"...
just a bug I haven't found...

I actually don't know what battle system would be better, whether turn based or ATB...
please give feedback if you use it or find some application!!

Pain/Blood System is actually compatible with most of battle system, since I used aliases and stuff like this...

If you want to improve it, feel free to customize, just advice me...

I fixed the bug in the main script... there shouldn't be any more left.


Jens

This post has been edited by Jens of Zanicuud: Dec 8 2011, 05:24 AM


__________________________
"Thorns are the rose's sweetest essence..."
-Jens of Zanicuud


Games I'm working on:
>

official website: TryAdIne eFfeCt

>

Games I worked on (mainly as a scripter):
>
(Warning: it's a 3rr3's project and it's in Italian!)


Awards

Go to the top of the page
 
+Quote Post
   
SleepingSirenx
post Dec 8 2011, 09:22 PM
Post #5


The SMT Maniac
Group Icon

Group: Revolutionary
Posts: 125
Type: Developer
RM Skill: Undisclosed




I see. Well, I think this will be good in a Tactical RPG, like FFTA or SMT : DS since players will be coping up with strategies on how to eliminate enemies' "Blood" life faster in order to win. And for example, if a character has a full "Pain" gauge, the player must think on how to support that character while thinking of winning. Well then. smile.gif


__________________________

My First Game .... Yeah .... ~♥
I'm In Need Of A Team To Help Me WIth The Development Of My Game PM Me. :)
- DEMO's On Progress!

I Support This Projects!



Please Teach Me How To Script. :(
I'm Learning How To Script. But Still Teach Me How To Script :)
Damn THERMODYNAMICS! Makes My Head Spin!
Go to the top of the page
 
+Quote Post
   

Closed TopicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 25th May 2013 - 11:55 AM
RPG RPG Revolution is an Privacy Policy and Legal
eXTReMe Tracker