ID:2641581
 
(See the best response by Kaiochao.)
Prenote - This is just from a game I'm making to play myself, on it's first day of creation. The entire will not be listed here but going to ask for your opinions of how to improve/make it faster. All of the code works.

Code:
AttackLock()
if(Lock == 1)
world<<"You're not in a battle..."
return
else
TypeCheck() //battle takes place for base dmg and
//weapon special
OffensivePlayerElementCheck()//weapon element
CriticalCheck()//critical check
DeathCheck()//damage occurs. all is what im showing.


The Above is what everything will proc first as a verb so might as well make it what's used immediately after relevant variables are created and/or set/checked.

The below is how we typecheck not only the weapon special, not crit like it says, but how we also typecheck between the three 'builds' of damage. (Hybrids possible) Melee, Magic, Ranged.


    TypeCheck()
Crit = WSC //32% with 15% wep at max level which gives around 2x bonus to all damage.
Crit += Intellect/50 //using 'floating' reusable crit variable to calculate weapon special %
Crit += Dexterity + Strength/90 //added to by stats
Crit += Luck/35
Crit += Charisma + Endurance /220
if(WSP == "Yes") //Not all weapons have specials.
switch(rand(100)) //out of 100
if(0 to Crit) //using our chance
world<<"[WText]" //weapon effect txt
if(WTYPE == "Magic") //type check
MagicDamage() //next step
FDamage = FDamage * WSM //<<
if(WTYPE == "Melee")//multiplier^^^^
MeleeDamage() //mult VVVV
FDamage = FDamage * WSM //<<
if(WTYPE == "Ranged") // mult^^^^
DexDamage()//from weapon..
FDamage = FDamage * WSM //ok
else //if no roll favor
if(WTYPE == "Magic") //same with no
MagicDamage()// mult from
if(WTYPE == "Melee")//weapon special
MeleeDamage()
if(WTYPE == "Ranged")
DexDamage()
else //if no mult at all..
if(WTYPE == "Magic") //type check
MagicDamage() //damage
if(WTYPE == "Melee") //e.t.c.
MeleeDamage()
if(WTYPE == "Ranged")
DexDamage()


Sorry for all the bad notation, WSM and stuff have to do with weapon's attributes, aiding in the creativity of their creation through offering alternatives, soon to add statuses.

Below is the damage formula, will example with strength.


    MeleeDamage()
FDamage = WepDamage + (Strength + Strength)
FDamage += 1 + (Level * 2.3) * ((1 * Luck/25) / 8.8)
FDamage += 1 + (Dexterity/1.9)
FDamage = (FDamage / 100) * (((Strength / 2.5) - Emeleedef) + 101) //max is 250 //% resist up to 100, but can be overcome with training in melee combat via strength. Min of 1% damage.)
FDamage = FDamage * DamMod (Damage Modifier for skills.)
txt = "Melee" (Test and for a later composite text part.)


Above is one example of damage, intellect relies less on other stats, only really itself, luck and endurance.

Below is OffensivePlayerElementCheck()
This is how I check element which is granted by weapon.


    OffensivePlayerElementCheck()
if(WELE == "Fire")
FDamage = (FDamage / 100) * EFIR
if(WELE == "Water")
FDamage = (FDamage / 100) * EWAT
if(WELE == "Earth")
FDamage = (FDamage / 100) * EEAR
if(WELE == "Air")
FDamage = (FDamage / 100) * EWIN
if(WELE == "Thunder")
FDamage = (FDamage / 100) * ETHU
if(WELE == "Ice")
FDamage = (FDamage / 100) * EICE
if(WELE == "Light")
FDamage = (FDamage / 100) * ELIG
if(WELE == "Darkness")
FDamage = (FDamage / 100) * EDAR
else
return
//fire water earth wind thunder ice light darkness


Above is for % resistance check, which you get from equipment, buffs, classes, e.t.c.

Below is for a critical check, also pretty standard, but could I be doing this faster? REINDENTED TO BE READABLE EASIER Not like this is my script

    CriticalCheck()
Crit = WepCrit
Crit = Luck/33
Crit += Dexterity/75
Crit += Strength/100
Crit += Charisma/125
switch(rand(100))
if(0 to Crit)
FDamage = FDamage * (1 + (Luck / 320) + ((Strength + Intellect + Dexterity) / 800) + (Charisma / 600))
switch(rand(6))
if(1)
FDamage = FDamage * (1 + (Luck / 1250) + (Strength / 2000))
world<<"An Astonishing blow!"
if(2)
FDamage = FDamage * (1 + (Luck / 1250) + (Intellect / 1925))
world<<"A Precise assault!"
if(3)
FDamage = FDamage * (1 + (Luck / 1250) + (Dexterity / 1850))
world<<"A Flanking attack!"
if(4)
FDamage = FDamage * 1.4
world<<"A Critical strike!"
if(5)
FDamage = FDamage * (1 + ((Strength + Dexterity + Intellect + Charisma + Luck + Endurance) / 10000))
world<<"An Awesome strik!"
if(6)
FDamage = FDamage * 1.6
world<<"A Perfect Attack!"
else
return
else
return //build special the same way, clear cast, e.t.c.)

Up there we check for critical and type of critical.

Below we check for death. Going to do a new exp system and stuff based off of overkill. Placeholder numbers for now.

    DeathCheck()
if(EHP <= 0)
world<<"The enemy is dead!"
else
EHP -= FDamage
world<<"You dealt [FDamage] [txt] [WELE] Damage!"
if(EHP<=0)
world<<"The enemy is slain! You gain [MonEXP] as Experience!"
EXP += MonEXP
Lock=1
</dm
<b>Problem description:</b>
It's just taking a bit and dunno if I'm doing things well.

Best response
All the WTYPE and WELE checks can be done slightly more efficiently as switch(WTYPE) and switch(WELE) instead of a series of if(). Especially since you're not using else-if, so there's no short-circuiting happening.

Your TypeCheck() can also be rearranged to reduce code duplication. Multiplying by WSM always happens after all WTYPE checks, if at all, so you can make that clearer:
switch(WTYPE)
if("Magic")
MagicDamage()
// etc.

Crit = // etc.
if(WSP && prob(Crit))
FDamage *= WSM


A common alternative to switch() in general is polymorphism. It's the more object-oriented approach. In your case, each weapon type and each weapon element can be represented by different objects that provide their own damage calculations and elemental modifiers. What they all have in common goes in the parent type, and how they differ goes in overrides of the child types:
weapon_type
// you may need to reference your attacker here to access their properties
// maybe pass it to Damage as an argument with the appropriate type
proc/Damage(whatever/attacker)

magic
Damage(whatever/attacker) // previously MagicDamage()
// do magic damage calculations

melee
Damage(whatever/attacker) // previously MeleeDamage()
var/damage = attacker.WepDamage + attacker.Strength * 2
// etc.
return damage

ranged
Damage() // previously RangedDamage()
// etc.

weapon_element
var/modifier = 100

proc/Modify(damage)
return damage / 100 * modifier

fire
modifier = EFIR

// etc.

To use this, your attacker's WTYPE and WELE vars would be replaced with instances of the appropriate /weapon_type and /weapon_element. Then, you would call the proc, and the appropriate calculation is done automatically, no type checks required. Something like this:
// This might be on the attacker, or on weapon objects, or whatever. 
// They can be assigned to any instance of their type, e.g. fire magic.
var/weapon_type/weapon_type = new/weapon_type/magic
var/weapon_element/weapon_element = new/weapon_element/fire

// then in the relevant procs

TypeCheck()
FDamage = weapon_type.Damage()

Crit = // etc.
if(WSP && prob(Crit))
FDamage *= WSM

OffensivePlayerElementCheck()
FDamage = weapon_element.Modify(FDamage)

More information about this particular code conversion here:
https://refactoring.guru/ replace-conditional-with-polymorphism
@WTYPE and WELE Check Code Condensing
-The switch proc works excellently for this, thank you. It'll also allow me to add any 'new elements' later on quite easily!

@Polymorphism/Object approach
-So, I generally agree with HOW you've changed the code in this manner and I'll probably use this type of approach for Statuses/Armor Bonuses, I want the weapon to be how it is simply due to my ignorance. I feel like I can do more with it having set variables than knowing how to imprint these variables temporarily and subtract them when it's unequipped and stuff without having clone variables otherwise, stored on the object or player.

-I would be fully embracing of this style of code with two realizations:
1. How to Generate New Items on a Proc
2. How to Unequip/Have Max Inventory Slots/Drop or Replace item.

Thank you for all of the help!
Also, would it be possible to do a switch searching proc from a list where I can enter one of two variables or none at all? I was thinking of affecting enemy distribution by element to allow for this by using Multiplicatives. By doing this I could order enemies also by low-high by strength to further reduce enemy generation.

(I'm using a T-100 Enemy System with 3 Lists, Random Battle, T-Tier List and T-Boss List) This means there's a randomizer that uses given variables to search between acceptable T's to scale to level, as level is one of these variables. T contains the enemies that you will fight and I'm going to implement a code that makes it so if you're above an enemies level, their stats will slightly raise relative to the gap between you. Will be easy to implement this by attaching it to another proc in generation.

So like, x3 = 3, 6, 9, 12, 15, 18, 24, 27, 30
x4 = 4, 8, 12, 16, 20, 24, 32, 36
x5 = 5, 10, 15, 20, 25, 30, 35
x6 = 6, 18, 30, 36, 42
x7 = 7, 14, 21, 28, 35, 41, 49.
Rolled to 50, rounds to nearest acceptable.
x3 would be, say, fire enemies,
x4 would be another type, e.t.c.


But could I use a list of words instead? Such as being able to search for two word variables instead.
Something like
switch(rand,"Element","Monster Name") //MName in my code
Where, if I only enter "Element" without monster name (never monster name without element), would it search for a random monster of that element within that Tier?