forked from flags/Reactor-3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
weapons.py
207 lines (151 loc) · 5.33 KB
/
weapons.py
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
from globals import *
import graphics as gfx
import life as lfe
import bad_numbers
import effects
import alife
import items
import random
def spawn_and_arm(weapon_name, feed_name, ammo_name, ammo_amount):
_weapon = ITEMS[items.create_item(weapon_name)]
_feed = ITEMS[items.create_item(feed_name)]
for i in range(ammo_amount):
_round = ITEMS[items.create_item(ammo_name)]
_feed['rounds'].append(_round['uid'])
_round['parent'] = _feed['uid']
_weapon[_feed['type']] = _feed['uid']
_feed['parent'] = _weapon['uid']
return _weapon['uid']
def get_weapon_to_fire(life):
if 'player' in life:
return life['firing']
_item = lfe.get_held_items(life,matches=[{'type': 'gun'}])
if _item:
_item = _item[0]
else:
return False
if not _item:
if 'player' in life:
gfx.message('You aren\'t holding a weapon!')
life['firing'] = None
return False
return lfe.get_inventory_item(life, _item)
def get_feed(weapon):
return weapon[weapon['feed']]
def get_fire_mode(weapon):
"""Returns current fire mode for a weapon."""
return weapon['firemodes'][weapon['firemode']]
def get_rounds_to_fire(weapon):
_mode = get_fire_mode(weapon)
if _mode == 'single':
_bullets = 1
elif _mode == '3burst':
_bullets = 3
else:
logging.error('Unhandled firerate: %s. Handling...' % _mode)
_bullets = 1
return _bullets
def change_fire_mode(weapon, mode):
weapon['firemode'] = mode
def get_stance_recoil_mod(life):
if life['stance'] == 'standing':
return 1.0
elif life['stance'] == 'crouching':
return .70
elif life['stance'] == 'crawling':
return .25
else:
1.0
def get_recoil(life):
_guns = lfe.get_held_items(life,matches=[{'type': 'gun'}])
if not _guns:
return 0
weapon = lfe.get_inventory_item(life, _guns[0])
_recoil = weapon['recoil']
_recoil *= get_stance_recoil_mod(life)
return _recoil
def get_accuracy(life, weapon_uid, limb=None):
weapon = ITEMS[weapon_uid]
_accuracy = 3*weapon['accuracy']
_accuracy *= alife.stats.get_firearm_accuracy(life)
if limb:
_stability = lfe.get_limb_stability(life, limb)
_accuracy *= _stability
if 'player' in life:
if _stability <= 0:
gfx.message('Your %s is useless.' % limb, style='damage')
return 0
elif _stability <= .25:
gfx.message('Your %s is nearly useless!' % limb, style='damage')
lfe.add_wound(life, limb, pain=2)
elif _stability <= .55:
gfx.message('You feel a sharp pain in your %s!' % limb, style='damage')
lfe.add_wound(life, limb, pain=1)
elif _stability <= .75:
gfx.message('Your %s stings from the recoil.' % limb, style='damage')
if life['stance'] == 'standing':
_accuracy *= 0.7
elif life['stance'] == 'crouching':
_accuracy *= 0.9
elif life['stance'] == 'crawling':
_accuracy *= 1
return _accuracy
def get_bullet_scatter_to(life, position, bullet_uid):
bullet = ITEMS[bullet_uid]
_travel_distance = bad_numbers.distance(bullet['pos'], position)
if _travel_distance <= 2:
return 0
return _travel_distance*bullet['scatter_rate']
def fire(life, target, limb=None):
#TODO: Don't breathe this!
weapon = get_weapon_to_fire(life)
if not weapon:
return False
_aim_with_limb = None
for hand in life['hands']:
if weapon['uid'] in lfe.get_limb(life, hand)['holding']:
_aim_with_limb = hand
_ooa = False
_feed_uid = get_feed(weapon)
if not _feed_uid:
if 'player' in life:
gfx.message('The weapon is unloaded.')
_ooa = True
return False
_feed = items.get_item_from_uid(_feed_uid)
if not _feed or (_feed and not _feed['rounds']):
if 'player' in life:
gfx.message('*Click* (You are out of ammo.)')
_ooa = True
return False
_bullet_deviation = (1-weapon['accuracy'])+life['recoil']
_deviation_mod = SETTINGS['aim_difficulty']*(1-((life['stats']['firearms']/10.0)*SETTINGS['firearms_skill_mod']))
_direction_deviation = (_bullet_deviation*SETTINGS['aim_difficulty'])*_deviation_mod
life['recoil'] = bad_numbers.clip(life['recoil']+(weapon['recoil']*get_stance_recoil_mod(life)), 0.0, 1.0)
_bullet_direction = bad_numbers.direction_to(life['pos'], target)+(random.uniform(-_direction_deviation, _direction_deviation))
alife.noise.create(life['pos'], 120, '%s fire' % weapon['name'], 'something discharge', target=life['id'])
#TODO: Clean this up...
_bullet = items.get_item_from_uid(_feed['rounds'].pop())
_bullet['pos'] = life['pos'][:]
_bullet['start_pos'] = life['pos'][:]
_bullet['owner'] = None
_bullet['shot_by'] = life['id']
_bullet['aim_at_limb'] = limb
items.add_to_chunk(_bullet)
if gfx.position_is_in_frame(life['pos']) or 'player' in life:
effects.create_light(life['pos'], tcod.yellow, 7, 1, fade=3.2)
effects.create_light(_bullet['pos'], tcod.yellow, 7, .9, fade=.65, follow_item=_bullet['uid'])
effects.create_smoke_cloud(life['pos'], 3, color=tcod.light_gray)
effects.create_smoke(life['pos'], color=tcod.yellow)
_bullet['accuracy'] = int(round(get_accuracy(life, weapon['uid'], limb=_aim_with_limb)))
print 'ACCURACY', _bullet['accuracy']
del _bullet['parent']
items.move(_bullet, _bullet_direction, _bullet['max_speed'])
_bullet['start_velocity'] = _bullet['velocity'][:]
items.tick_item(_bullet)
for _life in [LIFE[i] for i in LIFE]:
if _life['pos'][0] == target[0] and _life['pos'][1] == target[1]:
life['aim_at'] = _life['id']
break
if len(lfe.find_action(life, matches=[{'action': 'shoot'}])) == 1:
life['firing'] = None