-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTroika.lua
More file actions
228 lines (202 loc) · 6.01 KB
/
Troika.lua
File metadata and controls
228 lines (202 loc) · 6.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
math.randomseed(os.time())
local json = require("dkjson")
local weapons = {
['sword'] = {4,6,6,6,6,8,10},
['axe'] = {2,2,6,6,8,10,12},
['knife'] = {2,2,2,2,4,8,10},
['staff'] = {2,4,4,4,4,6,8},
['hammer'] = {1,2,4,6,8,10,12},
['spear'] = {4,4,6,6,8,8,10},
['longsword'] = {4,6,8,8,10,12,14},
['mace'] = {2,4,4,6,6,8,10},
['polearm'] = {2,4,4,8,12,14,18},
['maul'] = {1,2,3,6,12,13,14},
['greatsword'] = {2,4,8,10,12,14,18},
['club'] = {1,1,2,3,6,8,10},
['unarmed'] = {1,1,1,2,2,3,4},
['shield'] = {2,2,2,4,4,6,8},
['fusil'] = {2,4,4,6,12,18,24},
['bow'] = {2,4,6,8,8,10,12},
['crossbow'] = {4,4,6,8,8,8,10},
['pistolet'] = {2,2,4,4,6,12,16},
['small'] = {2,2,3,3,4,5,6},
['modest'] = {4,6,6,8,8,10,12},
['large'] = {4,6,8,10,12,14,16},
['gigantic'] = {4,8,12,12,16,18,24},
['firebolt'] = {3,3,5,7,9,12,16},
['jolt'] = {2,2,3,3,5,7,9},
['dragonfire'] = {6,8,12,16,18,24,36}
}
local theBag = {}
local entities = {}
function main()
local encounter = loadJSON("fight.json")
local playerWins = 0
loadBag(encounter)
for i=1, 1000, 1 do
playerWins = playerWins + simulateFight()
loadBag(encounter)
end
print("Out of 1000 battles, the players won " .. playerWins/10 .. "% of the time.")
end
function fight(e1, e2)
local e1roll = math.random(1,6) + math.random(1,6)
local e2roll = math.random(1,6) + math.random(1,6)
local rangedWeapons = {
fusil = true,
bow = true,
crossbow = true,
pistolet = true,
firebolt = true,
jolt = true,
dragonfire = true,
}
local isRanged = rangedWeapons[e1.weapon]
local unDodgeableWeapons = {
firebolt = true,
jolt = true,
dragonfire = true,
}
local isUnDodgeable = unDodgeableWeapons[e1.weapon]
--Dual Mighty Blow
if e1roll == 12 and e2roll == 12 then
e1.stamina = e1.stamina - math.random(1,6)
e2.stamina = e2.stamina - math.random(1,6)
return
end
--Tie
if (e1.skill + e1roll == e2.skill + e2roll) and e1roll ~= 12 and e2roll ~= 12 then return end
--Who hits?
local winner = e1
local loser = e2
local mightyBlow = e1roll == 12
if not mightyBlow and not isUnDodgeable and ((e1.skill + e1roll < e2.skill + e2roll) or e2roll == 12) then
winner = e2
loser = e1
mightyBlow = e2roll == 12
end
--Enemy dodges, no damage dealt
if winner == e2 and isRanged then return end
--how much damage
local damageRoll = math.random(1,6)
local mightyBlowDamageRoll = math.random(1,6)
local noArmorWeapons = {
hammer = true,
mace = true,
polearm = true,
maul = true,
fusil = true,
pistolet = true,
jolt = true,
large = true,
gigantic = true,
}
if not noArmorWeapons[winner.weapon] then
damageRoll = damageRoll - loser.armor
mightyBlowDamageRoll = mightyBlowDamageRoll - loser.armor
end
noArmorWeapons['jolt'] = false
if noArmorWeapons[winner.weapon] and loser.armor > 0 then
damageRoll = damageRoll - (loser.armor-1)
mightyBlowDamageRoll = mightyBlowDamageRoll - (loser.armor-1)
end
if damageRoll <= 0 then damageRoll = 1 end
if mightyBlowDamageRoll <= 0 then mightyBlowDamageRoll = 1 end
local damage = weapons[winner.weapon][damageRoll]
if mightyBlow then damage = damage + weapons[winner.weapon][mightyBlowDamageRoll] end
loser.stamina = loser.stamina - damage
end
function loadJSON(path)
local file = io.open(path, "r")
if not file then
return nil, "Could not open file: " .. path
end
local content = file:read("*a")
file:close()
local obj, pos, err = json.decode(content, 1, nil)
if err then
return nil, "JSON parse error: " .. err
end
return obj
end
function loadBag(encounter)
theBag = {}
entities = {}
for _,v in ipairs(encounter) do
local entity = {}
entity.id = v.id
entity.team = v.team
entity.stamina = v.stamina
entity.skill = v.skill
entity.armor = v.armor
entity.initiative = v.initiative
entity.weapon = v.weapon
entities[entity.id] = entity
for i = 1, entity.initiative, 1 do
local bagEntry = {}
bagEntry.id = entity.id
bagEntry.team = entity.team
table.insert(theBag,bagEntry)
end
end
local bagEntry = {}
bagEntry.id = 'round'
bagEntry.team = 'round'
table.insert(theBag,bagEntry)
end
function simulateFight()
local numPlayers
local numEnemies
while true do
numPlayers = 0
numEnemies = 0
--Did Players win?
for k,v in ipairs(theBag) do
if v.team == "Player" then numPlayers = numPlayers + 1 end
if v.team == "Enemy" then numEnemies = numEnemies + 1 end
end
if numEnemies == 0 and numPlayers == 0 then return 0 end
if numEnemies == 0 then return 1 end
if numPlayers == 0 then return 0 end
--Get Next Turn
local randomTurn = math.random(#theBag)
local turnHolder = theBag[randomTurn]
--Remove turnHolder From Bag
table.remove(theBag,randomTurn)
--If End of round token is drawn, start new round
if turnHolder.id == 'round' then
theBag = {}
for k,entity in pairs(entities) do
local bagEntry = {}
bagEntry.id = entity.id
bagEntry.team = entity.team
table.insert(theBag,bagEntry)
end
local bagEntry = {}
bagEntry.id = 'round'
bagEntry.team = 'round'
table.insert(theBag,bagEntry)
end
--Get ID of opposite Team
if turnHolder.id ~= 'round' then
turnHolder = entities[turnHolder.id]
randomTurn = math.random(#theBag)
while theBag[randomTurn].id == 'round' or theBag[randomTurn].team == turnHolder.team do
randomTurn = math.random(#theBag)
end
local attackee = entities[theBag[randomTurn].id]
--Fight one round
fight(turnHolder,attackee)
--remove dead
for k,v in pairs(entities) do
if v.stamina <= 0 then
for i=#theBag, 1, -1 do
if theBag[i].id == v.id then table.remove(theBag,i) end
end
entities[k] = nil
end
end
end
end
end
main()