Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Tales of MajEyal
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Otowa Kotori
Tales of MajEyal
Commits
9bd0ac25
Commit
9bd0ac25
authored
10 years ago
by
Hachem_Muche
Browse files
Options
Downloads
Patches
Plain Diff
Added attrPowers function.
develop resolvers.calc.talented_ai_tactic
parent
b4b1a6dc
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
game/modules/tome/class/GameState.lua
+31
-26
31 additions, 26 deletions
game/modules/tome/class/GameState.lua
game/modules/tome/resolvers.lua
+22
-11
22 additions, 11 deletions
game/modules/tome/resolvers.lua
with
53 additions
and
37 deletions
game/modules/tome/class/GameState.lua
+
31
−
26
View file @
9bd0ac25
...
...
@@ -258,21 +258,34 @@ _M.power_themes = {
--- defined power sources, used for equipment generation, defined in class descriptors
_M
.
power_sources
=
table
.
map
(
function
(
k
,
v
)
return
k
,
true
end
,
table
.
keys_to_values
({
'technique'
,
'technique_ranged'
,
'nature'
,
'arcane'
,
'psionic'
,
'antimagic'
}))
--- map attributes to power restrictions for an entity
-- returns an updated list of forbidden power types including attributes
function
_M
:
attrPowers
(
e
,
not_ps
)
not_ps
=
table
.
clone
(
not_ps
or
e
.
not_power_source
or
e
.
forbid_power_source
)
or
{}
if
e
.
attr
then
if
e
:
attr
(
"has_arcane_knowledge"
)
then
not_ps
.
antimagic
=
true
end
if
e
:
attr
(
"undead"
)
then
not_ps
.
nature
=
true
not_ps
.
antimagic
=
true
end
if
e
:
attr
(
"forbid_arcane"
)
then
not_ps
.
arcane
=
true
end
if
e
:
attr
(
"forbid_nature"
)
then
not_ps
.
nature
=
true
end
end
return
not_ps
end
--- Checks power_source compatibility between two entities
-- returns true if e2 is compatible with e1, false otherwise
-- by default, only checks .power_source vs. .forbid_power_source between entities
-- if require_power is true, it will also check that e2.power_source (if present) has a match in e1.power_source
-- use update
_p
ower
_source
to resolve conflicts.
function
_M
:
check
_p
ower
_source
(
e1
,
e2
,
require_power
)
-- use update
P
ower
s
to resolve conflicts.
function
_M
:
check
P
ower
s
(
e1
,
e2
,
require_power
)
if
not
e1
or
not
e2
then
return
true
end
local
ok
=
true
--print("Comparing power sources",e1.name, e2.name)
-- check for excluded power sources first
local
not_ps
=
e2
.
not_power_source
or
e2
.
forbid_power_source
or
{}
local
not_ps
=
self
:
attrPowers
(
e2
)
for
ps
,
_
in
pairs
(
e1
.
power_source
or
{})
do
if
not_ps
[
ps
]
then
return
false
end
end
not_ps
=
e1
.
not_power_source
or
e1
.
forbid_power_source
or
{}
not_ps
=
self
:
attrPowers
(
e1
)
for
ps
,
_
in
pairs
(
e2
.
power_source
or
{})
do
if
not_ps
[
ps
]
then
return
false
end
end
...
...
@@ -295,7 +308,7 @@ end
-- themes included can add to forbid_ps and allow_ps
-- precedence is: forbid_ps > allow_ps > force_themes
-- returns forbid_ps, allow_ps, themes (made consistent)
function
_M
:
update
_p
ower
_source
(
forbid_ps
,
allow_ps
,
randthemes
,
force_themes
)
function
_M
:
update
P
ower
s
(
forbid_ps
,
allow_ps
,
randthemes
,
force_themes
)
local
spec_powers
=
allow_ps
and
next
(
allow_ps
)
local
yes_ps
=
spec_powers
and
table
.
clone
(
allow_ps
)
or
table
.
clone
(
self
.
power_sources
)
local
not_ps
=
forbid_ps
and
table
.
clone
(
forbid_ps
)
or
{}
...
...
@@ -403,7 +416,7 @@ function _M:generateRandart(data)
local
o
=
base
:
cloneFull
()
o
.
baseobj
=
base
:
cloneFull
()
-- debugging code
o
.
gendata
=
table
.
clone
(
data
,
true
)
o
.
gendata
=
table
.
clone
(
data
,
true
)
-- debugging code
-- Load possible random powers
local
powers_list
=
engine
.
Object
:
loadList
(
o
.
randart_able
,
nil
,
nil
,
...
...
@@ -430,12 +443,12 @@ o.gendata = table.clone(data, true)
psource
=
table
.
clone
(
o
.
power_source
)
if
data
.
power_source
then
table
.
merge
(
psource
,
data
.
power_source
)
end
-- forbid power sources that conflict with existing power source
data
.
forbid_power_source
,
psource
=
self
:
update
_p
ower
_source
(
data
.
forbid_power_source
,
psource
)
data
.
forbid_power_source
,
psource
=
self
:
update
P
ower
s
(
data
.
forbid_power_source
,
psource
)
if
data
.
power_source
then
data
.
power_source
=
psource
end
end
-- resolve any power/theme conflicts with input data
local
themes
data
.
forbid_power_source
,
psource
,
themes
=
self
:
update
_p
ower
_source
(
data
.
forbid_power_source
,
data
.
power_source
,
nb_themes
,
data
.
force_themes
)
data
.
forbid_power_source
,
psource
,
themes
=
self
:
update
P
ower
s
(
data
.
forbid_power_source
,
data
.
power_source
,
nb_themes
,
data
.
force_themes
)
if
data
.
power_source
then
data
.
power_source
=
psource
end
themes
=
table
.
map
(
function
(
k
,
v
)
return
k
,
true
end
,
table
.
keys_to_values
(
themes
))
...
...
@@ -564,7 +577,7 @@ o.gendata = table.clone(data, true)
if
ignore_filter
then
return
true
end
if
not
ef
.
special
or
ef
.
special
(
e
)
then
if
gr_ego
and
not
e
.
greater_ego
then
return
false
end
return
game
.
state
:
check
_p
ower
_source
(
ef
,
e
,
true
)
-- check power_source compatibility
return
game
.
state
:
check
P
ower
s
(
ef
,
e
,
true
)
-- check power_source compatibility
end
end
...
...
@@ -746,7 +759,6 @@ o.gendata = table.clone(data, true)
end
o
.
combat
.
damtype
=
pickDamtype
(
themes
)
end
-- if o and o.combat and not (o.subtype and o.subtype == "staff") and not (o.subtype and o.subtype == "mindstar") then o.combat.damtype = pickDamtype(themes) end
if
data
.
post
then
data
.
post
(
o
)
...
...
@@ -760,9 +772,8 @@ o.gendata = table.clone(data, true)
end
--- Adds randart properties (egos and random powers) to an existing object
-- o is the object to be updated
-- o is the object to be updated
(o.egos and o.randart_able should be defined as needed)
-- data is the table of randart parameters passed to generateRandart
-- o.egos and o.randart_able should be defined as needed
-- usable powers and set properties are not overwritten if present
function
_M
:
addRandartProperties
(
o
,
data
)
print
(
" ** adding randart properties to "
,
o
.
name
,
o
.
uid
)
...
...
@@ -1909,12 +1920,11 @@ end
-- data.no_class_restrictions set true to skip class compatibility checks <nil>
-- data.add_trees = {["talent tree name 1"]=true, ["talent tree name 2"]=true, ..} additional talent trees to learn
-- data.check_talents_level set true to enforce talent level restrictions <nil>
-- data.auto_sustain
set true to activate sustained talents at birth <nil>
-- data.auto_sustain set true to activate sustained talents at birth <nil>
-- data.forbid_equip set true for no equipment <nil>
-- data.loot_quality = drop table to use <"boss">
-- data.drop_equipment set true to force dropping of equipment <nil>
-- instant set true to force instant learning of talents and generating golem <nil>
-- returns true if the class was successfully added
function
_M
:
applyRandomClass
(
b
,
data
,
instant
)
if
not
data
.
level
then
data
.
level
=
b
.
level
end
...
...
@@ -1944,13 +1954,8 @@ function _M:applyRandomClass(b, data, instant)
-- b.forbid_power_source --> b.not_power_source used for classes
b
.
power_source
=
table
.
merge
(
b
.
power_source
or
{},
class
.
power_source
or
{})
b
.
not_power_source
=
table
.
merge
(
b
.
not_power_source
or
{},
class
.
not_power_source
or
{})
if
b
:
attr
(
"has_arcane_knowledge"
)
or
b
:
attr
(
"undead"
)
then
b
.
not_power_source
.
antimagic
=
true
end
if
b
:
attr
(
"undead"
)
then
b
.
not_power_source
.
nature
=
true
end
if
b
:
attr
(
"forbid_arcane"
)
then
b
.
not_power_source
.
arcane
=
true
end
if
b
:
attr
(
"forbid_nature"
)
then
b
.
not_power_source
.
nature
=
true
end
-- update power source parameters with the new class
b
.
not_power_source
,
b
.
power_source
=
self
:
update
_p
ower
_source
(
b
.
not_power_source
,
b
.
power_source
)
b
.
not_power_source
,
b
.
power_source
=
self
:
update
P
ower
s
(
self
:
attrPowers
(
b
,
b
.
not_power_source
)
,
b
.
power_source
)
print
(
" power types: not_power_source ="
,
table.concat
(
table
.
keys
(
b
.
not_power_source
),
","
),
"power_source ="
,
table.concat
(
table
.
keys
(
b
.
power_source
),
","
))
-- Add stats
...
...
@@ -2019,7 +2024,6 @@ print(" power types: not_power_source =", table.concat(table.keys(b.not_power_
ok
=
false
end
end
if
ok
then
list
[
t
.
id
]
=
true
end
end
end
...
...
@@ -2060,7 +2064,7 @@ print(" power types: not_power_source =", table.concat(table.keys(b.not_power_
while
to_apply
>
0
do
local
c
=
rng
.
tableRemove
(
list
)
if
not
c
then
break
end
--repeat attempts until list is exhausted
if
data
.
no_class_restrictions
or
self
:
check
_p
ower
_source
(
b
,
c
)
then
-- recheck power restricts here to account for any previously picked classes
if
data
.
no_class_restrictions
or
self
:
check
P
ower
s
(
b
,
c
)
then
-- recheck power restricts here to account for any previously picked classes
if
apply_class
(
table
.
clone
(
c
,
true
))
then
to_apply
=
to_apply
-
1
end
else
print
(
" class"
,
c
.
name
,
" rejected due to power source"
)
...
...
@@ -2080,7 +2084,8 @@ end
-- data.life_rating <1.7 * base.life_rating + 4-9>
-- data.resources_boost = multiplier for maximum resource pool sizes <3>
-- data.talent_cds_factor = multiplier for all talent cooldowns <1>
-- data.ai <"tactical" if rank>3 or base.ai>
-- data.ai = ai_type <"tactical" if rank>3 or base.ai>
-- data.ai_tactic = tactical weights table for the tactical ai <nil>
-- data.no_loot_randart set true to not drop a randart <nil>
-- data.on_die set true to run base.rng_boss_on_die and base.rng_boss_on_die_custom on death <nil>
-- data.name_scheme <randart_name_rules.default>
...
...
@@ -2107,6 +2112,7 @@ function _M:createRandomBoss(base, data)
b
.
name
=
name
..
" the "
..
b
.
name
end
print
(
"Creating random boss "
,
b
.
name
,
data
.
level
,
"level"
,
data
.
nb_classes
,
"classes"
)
if
data
.
force_classes
then
print
(
" * forcing classes:"
,
table.concat
(
table
.
keys
(
data
.
force_classes
),
","
))
end
b
.
unique
=
b
.
name
b
.
randboss
=
true
local
boss_id
=
"RND_BOSS_"
..
b
.
name
:
upper
():
gsub
(
"
[^
A-Z
]
"
,
"_"
)
...
...
@@ -2151,7 +2157,6 @@ function _M:createRandomBoss(base, data)
else
b
.
ai
=
(
b
.
rank
>
3
)
and
"tactical"
or
b
.
ai
end
b
.
ai_state
=
{
talent_in
=
1
,
ai_move
=
data
.
ai_move
or
"move_astar"
}
b
.
ai_tactic
=
resolvers
.
talented_ai_tactic
()
-- Remove default equipment, if any
local
todel
=
{}
...
...
@@ -2213,8 +2218,8 @@ function _M:createRandomBoss(base, data)
self
:
resetToFull
()
end
--
resolve
ai
tactic
al weights here?
-- b
.ai_tactic = resolvers.talented_ai_tactic(
)
--
b.ai_tactic = data.ai_tactic or resolvers.talented_
ai
_
tactic
() --Update tactics based on talents
-- b
:resolve(nil, true
)
-- Anything else
if
data
.
post
then
data
.
post
(
b
,
data
)
end
...
...
This diff is collapsed.
Click to expand it.
game/modules/tome/resolvers.lua
+
22
−
11
View file @
9bd0ac25
...
...
@@ -51,9 +51,10 @@ function resolvers.calc.equip(t, e)
filter
.
random_art_replace
.
chance
=
100
end
end
if
o
and
o
.
power_source
and
(
o
.
power_source
.
antimagic
and
e
:
attr
(
"has_arcane_knowledge"
)
or
o
.
power_source
.
arcane
and
e
:
attr
(
"forbid_arcane"
))
then
-- if o and o.power_source and (o.power_source.antimagic and e:attr("has_arcane_knowledge") or o.power_source.arcane and e:attr("forbid_arcane")) then
if
o
and
not
filter
.
no_power_restrictions
and
not
game
.
state
:
checkPowers
(
e
,
o
)
then
-- Check power restrictions
ok
=
false
print
(
" Equipment resolver for "
,
e
.
name
,
" -- incompatible equipment "
,
o
.
name
,
"retrying"
,
tries
,
"forbid ps:"
,
filter
.
forbid_power_source
and
table.concat
(
table
.
keys
(
filter
.
forbid_power_source
,
","
)))
print
(
" Equipment resolver for "
,
e
.
name
,
" -- incompatible equipment "
,
o
.
name
,
"retrying"
,
tries
,
"forbid ps:"
,
filter
.
forbid_power_source
and
table.concat
(
table
.
keys
(
filter
.
forbid_power_source
,
","
)),
"vs ps"
,
o
.
power_source
and
table.concat
(
table
.
keys
(
o
.
power_source
,
","
)))
end
until
ok
or
tries
>
4
if
o
then
...
...
@@ -635,19 +636,21 @@ end
function
resolvers
.
calc
.
talented_ai_tactic
(
t
,
e
)
local
tactic_total
=
t
[
2
]
or
t
.
tactic_total
or
10
--want tactic weights to total 10
local
weight_power
=
t
[
3
]
or
t
.
weight_power
or
0
.
5
--smooth out tactical weights
local
tacs_offense
=
{
attack
=
1
,
attackarea
=
1
,
disable
=
0
.
5
}
local
tacs_offense
=
{
attack
=
1
,
attackarea
=
1
}
local
tacs_close
=
{
closein
=
1
,
go_melee
=
1
}
local
tacs_defense
=
{
escape
=
1
,
defend
=
1
,
heal
=
1
,
protect
=
1
,
disable
=
0
.
5
}
local
tacs_defense
=
{
escape
=
1
,
defend
=
1
,
heal
=
1
,
protect
=
1
,
disable
=
1
}
local
tac_types
=
{
type
=
"melee"
,
type
=
"ranged"
,
type
=
"tank"
,
type
=
"survivor"
}
local
tactic
,
tactical
=
{},
{
total
=
0
}
local
count
=
{
talents
=
0
,
atk_count
=
0
,
atk_value
=
0
,
atk_melee
=
0
,
atk_range
=
0
,
total_range
=
0
,
close_count
=
0
,
def_count
=
0
,
def_value
=
0
,
disable
=
0
}
local
count
=
{
talents
=
0
,
atk_count
=
0
,
atk_value
=
0
,
total_range
=
0
,
atk_melee
=
0
,
melee_value
=
0
,
range_value
=
0
,
atk_range
=
0
,
escape
=
0
,
close
=
0
,
def_count
=
0
,
def_value
=
0
,
disable
=
0
}
local
do_count
,
val
local
tac_count
=
#
table
.
keys
(
tacs_offense
)
+
#
table
.
keys
(
tacs_close
)
+
#
table
.
keys
(
tacs_defense
)
-- go through all talents, adding up all the tactical weights from the tactical tables weighted by talent level
for
tid
,
tl
in
pairs
(
e
.
talents
)
do
local
tal
=
e
:
getTalentFromId
(
tid
)
local
range
=
e
:
getTalentRange
(
tal
)
+
e
:
getTalentRadius
(
tal
)
*
2
/
3
local
range
=
e
:
getTalentRange
(
tal
)
if
range
>
0
then
range
=
range
+
e
:
getTalentRadius
(
tal
)
*
2
/
3
end
if
tal
and
tal
.
tactical
then
do_count
=
false
for
tt
,
wt
in
pairs
(
tal
.
tactical
)
do
...
...
@@ -655,29 +658,34 @@ function resolvers.calc.talented_ai_tactic(t, e)
if
type
(
wt
)
==
"number"
then
val
=
wt
elseif
type
(
wt
)
==
"table"
then
for
_
,
n
in
pairs
(
wt
)
do
if
type
(
n
)
==
"number"
then
val
=
val
+
n
end
if
type
(
n
)
==
"number"
then
val
=
math.max
(
val
,
n
)
end
end
if
val
==
0
then
val
=
2
end
end
tactical
[
tt
]
=
(
tactical
[
tt
]
or
0
)
+
val
-- sum up all the input weights
if
tacs_offense
[
tt
]
then
do_count
=
true
count
.
atk_count
=
count
.
atk_count
+
1
count
.
atk_value
=
count
.
atk_value
+
tacs_offense
[
tt
]
*
val
val
=
val
*
tacs_offense
[
tt
]
count
.
atk_value
=
count
.
atk_value
+
val
count
.
total_range
=
count
.
total_range
+
range
if
range
>=
2
then
count
.
atk_range
=
count
.
atk_range
+
1
count
.
range_value
=
count
.
range_value
+
val
else
count
.
atk_melee
=
count
.
atk_melee
+
1
count
.
melee_value
=
count
.
melee_value
+
val
end
end
if
tacs_defense
[
tt
]
then
do_count
=
true
count
.
def_count
=
count
.
def_count
+
1
count
.
def_value
=
count
.
def_value
+
tacs_defense
[
tt
]
*
val
if
tt
==
"escape"
then
count
.
escape
=
count
.
escape
+
1
end
end
if
tacs_close
[
tt
]
then
do_count
=
true
count
.
close
_count
=
count
.
close
_count
+
1
count
.
close
=
count
.
close
+
1
end
if
do_count
then
count
.
talents
=
count
.
talents
+
1
...
...
@@ -711,7 +719,8 @@ function resolvers.calc.talented_ai_tactic(t, e)
end
-- Minimum range?
if
count
.
atk_range
>
count
.
atk_melee
and
(
count
.
atk_range
-
count
.
close_count
)
/
(
count
.
atk_melee
+
1
)
>
2
then
-- if count.atk_range > count.atk_melee and (count.atk_range + count.escape - count.close)/(count.atk_melee + 1) > 2 then
if
count
.
atk_range
+
count
.
escape
>
count
.
atk_melee
+
count
.
close
and
count
.
range_value
/
(
count
.
melee_value
+
1
)
>
1
.
5
then
tactic
.
safe_range
=
math.max
(
2
,
math.ceil
(
count
.
avg_attack_range
/
2
))
--only for ranged/survivor
end
...
...
@@ -719,6 +728,8 @@ function resolvers.calc.talented_ai_tactic(t, e)
tactic
.
tactical_sum
=
tactical
tactic
.
count
=
count
tactic
.
type
=
ttype
tactic
.
tac_count
=
tac_count
print
(
"talented_ai_tactic resolver for"
,
e
.
name
,
"level="
,
e
.
level
)
for
tac
,
wt
in
pairs
(
tactic
)
do
print
(
" ##"
,
tac
,
wt
)
end
return
tactic
end
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment