aboutsummaryrefslogblamecommitdiff
path: root/src/GameTick.cpp
blob: 071993bf12676a9457da8caaa88cf48b1736dda2 (plain) (tree)
1
2
3
4
5
6
7
8

                                  
                                     


                                          
                                  
                                              














                                                                         
 
                    
 
                 
                 
 
                        
                       
                   
                       
                                  
                     
                         
               
                       
                               
                               
                       
                                  
                              
                 

                     

                     
                             


                         
 






                                              
                          
                            


                                                                  

                                       
                                        

                                       


                                                                             
                                                                        
                                                       
                                                           
         
 
                                                              
                        


                                              


                                                                 

 
                           





                                                    


                                                              
 



                                                   
            
                                            
 



                                                              
 
 
                                                        
 
                         
                                                     






                                                                      
                                

                                                         
                                           
                                                              






                                                             



                                                
                                         


























                                                                                  

                              
                                          
                       
         
 

                                       
 

















                                                                    
                                                     

















                                                                             

                 






                                                
 





















                                                                             

                 



































                                                                                    
                                                        

                                                                                      









                                                                             

                                                                            




                                                                  

                                                                            

                         

         
 
                                               
 












                                                                             
                       



                                                      
 
                                    
                                                                           


                                                      
                                                                              
                                                                               
                                               
 



                                                          


                                                       



                                                                              
         

 
                                        











                                                                      
                         
 
                                                       
                                                                            
                                            
 
                                           






                                       

                                                                    



                                       
                                                           


                                                                  

                      
 
                                         
                                                            
 
 
                             
 
                                    
                                
                               











                                  


                                                    
                                
 
                                              
                                           





                                                                  
                                                      

                                                                    
                          
                                                                      
                                                                               
                                          

 





























                                                                      

















































































                                                                                                                                 

                 


                                                                             
                                            
 

                                
 

                                                                   
 

                                             
                                                     
 
                                 
                               
         
 
                          
                         
 
                 
                              
                                                             
                                                            
 
                                
                         
                               
 
                                         
                        
                        
                 
                     
                       
                      
                                                                      
 


                                                  
 




                                                                    

                                                              
 



                                                                       
 

                                 
 






                                                              
 
                                                                                                                                 
                                                                                                                                                                                                  

                                                                                                                              
                                           
                         
                 
 
                                                   
                                                                                      
                                                          
                                                          
                                             
                                                
                                                   
                                                      
 
                                                                                                                            
 
                                                                             
 
                 
 
                                                                                        
 
                                                                                        
 
                                                                         
 
                                                                         
 
                                                                                            
 
                                                                                            
 
                                                                            
 
                                                                                 
 
                                                  
 
                                                           
 
                                                                                                       
 
                                          
 
                                             
 
                                                                        
 
                                             
 
                                                
 
                                                    
 
                                                            
 
                                                               
 
                                                
 
                                                                                                                                                                                                                                                                
 
                                                                                                                                                                                                                                                                    
 
                                                                                                                     
 
                                                                                  
 
                                                                
 
                            
 
                                                          
 
                              
 
         
 
                                                
 
                                             
 
                           
 
                                                                                                                                                                                                                                                                                                      
 
                                
 
                                   
 
                                                     
 
                 
 
                                                          





                                                                  
 
                                                                                                                                     
                                                                                                                                                                                                          

                                                                                                                                      
                                                   
                                 
                         
 
                                                       
                                                                                          
                                                                                              
                                                              
                                                              
                                                 
                                                    
                                                       
                                                          
 
                                                                                                                        
                                                                                 
                         
 
                                                                                        
 
                                                                                        
 
                                                                            
 
                                                                         
 
                                                                                            
 
                                                                                            
 
                                                                            
 
                                                                                 
 
                                                      
 
                                                               
 
                                                                                                       
 
                                              
 
                                                 
 
                                                                            
 
                                                 
 
                                                    
 
                                                        
 
                                                                     
 
                                                                                                                                                                                                                                             
 
                                                                                                                                                                                                                                               
 
                                                                                                                 
 
                                                                
 
                                                                    
 
                                                            
 
                                                                  
 
                                
 
                                      
 
                 
 















                                                                                         
                                                                                      
                                                  
                                                                                       
                                                   
 




                                                                                      
 

                                                                                                                                                                   
 
                                                               



                                                                                                                                                                                     
                                                                                         
                                                   
                                                  
                                                                                                                  

                                 
                                                          
 

                         
                 
 
                                                                     
                                                                 
                 
 
                                                                     

                                                                                                             
                 
 
                                                                                                 

                                                                                                             
                 
 
                                                                    

                                                                   



                                                                
 
                                                                     

                                                                         

                                                                             
                                 


                                                                        

                                                                                   
                 
 










                                                                                                                                                                             
                                         
                                                                                                                       

                         
                 
 

















                                                                           
                                 

                                                                 













                                                                           
                                 
                                      
                         

                                                     
 



                                                                        

                                                                                                     

                                                     
                                                                                                                                                                                                                  
                                                                                                         
                                                                                                                                                                                                                          
                                                                                                                  
                                                                                              
                                                                                                                                                                                                                                             

                                 

                                                                                                     

                                                                        
 



                                                                                                                                
 


                                                                                                   
 
                                               
 






                                                                                


                                                                               









                                                                                
 




                                                                                                               
 
                                                                                                                                                                     













                                                                                                                      



                                                                                                                                                                                                                                  
                                                         











                                                                                                                      
                                                 
                                         
 



                                                                                  


                                                                                             


                                                                        




                                                                                 
 

                                                                                  
 


                                                                                         








                                                                                               





                                                                                                                          










                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 




                                                                                 
 


                                                                                           


                                                 
 
                                                   
                                                                                                                        
                                                               
                                                                                                                     










                                                                                                                       
                                                                                                  





















                                                                                                                                                   
                                                              


                                                                                     
 


                                                                                                











                                                                                                                                                                                                                                                                                                                                                                                                            
                                                 
 


                                                                                                











                                                                                                                                                                                                                                                                                                                                                                                                            
                                                 
 


                                                                                                          








                                                                                               
                                                                                      
                                                                                              
                                                                                                                               
 

                                                                                                                        











                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 



                                                                                 
                                                          
                                                 
 

                                                                           



                                                                                         
 






                                                                                                                                                                                              
                                                                                                                     
 

                                                                                       







                                                                                               
                                                                                      
                                                                                              
                                                                                               


                                                                                                        





                                                                                                                                                                                                              
                                                          

                                                         

                                                                                                                                       
                                                                                                          
                                                                  
 
                                                                                                  
                                                                                           
                                                                  
 
                                                                                                 




                                                                                                            
                                                                                                                                          


                                                                                                                                                  
 
                                                                                                                                              
 
                                                                                           
 
                                                                                                                    
 
                                                                                                                                                                    
 
                                                                                                                                                                                                       
 

                                                                                      
 



                                                                                                        
 



                                                                                                             
 



                                                                                                            
 



                                                                                                      
 

                                                                                                                                                                      
 


                                                                                                                                                                                                                                                                                                                                                                                                                                                    


                                                                                                                
 




                                                                                                                                                        

                                                                                                                                         


                                                                                                                                                                     

                                                                                                                                                                                         






                                                                                                                                                           
                                                                                         
                                                                                 
                                                                         
                                                                                                                              

                                                                  
 

                                                                                                                                       
                                                                                                                
                                                                  
 
                                                                                                  
                                                                                           
                                                                  
 
                                                                                                 


                                                                                                            
 
                                                                                                                                              
 

                                                                                                                                                                                                       
 



                                                                                                                                                                    
                                                                         
                                                                                                                              
                                                                  
                                                         
 

                                                                                                                                                                            
                                                 
                                         
 




                                                                                                                     
                                         
                                 
                         
 

                                                                                                         
                                                                                        
                                                                                                                         
 


                                                            

                                                          
 







                                                                                                                    
                                 
                         
                  
 
                          


                                                                                                                        
 




                                                                              
                                                       
 



                                                                                                                                                                                                                                        
                                                  
 

                                                                       
 
                                                           


                                                                                                                                         

                 














                                                                                                                  


                                                                                    
 
                                          
                                                                                                                        
                                             



                                                                                              
                                                      

                                                                                                   
                                                              

                                                                                                                                                        
                         
                 
         
 
                     
 
                                                                                                     
 
                                                                                                                                                                                                          

                                                                           

                                                                              

                                                                                    
                                        

                                                                                    
 

                                                                                                                                 
                                                                                
                                                                                  

                                                                                                
 
                                                             
                                                               
 
                                                                                                       
                                                       


                                                                                                                                                                                                                                                                             
                                 
 
                                                                         
                                                                             
                                                                        
 





                                                                                                    


                                                                           
                                 
 
                                                              

                                                                                                                                      
                                 







                                                                                    
 

                                                                                                                                 
 
                                                                                  
 

                                                                                                
 

                                                               
 

                                                                                                       
 


                                                                                                                                                                                                                                                                             
                                 
 



                                                                             
 




                                                                                                                                       
 


                                                                           
                                 
 
                                                              

                                                                                                                                      
                                 
                         
                 









                                                                       
 
                                      


                                                                    
                          
 











                                                                                                            


                                                                   
                         

                 
 

                                                      


                                                                         
                                         
         
 


                         





                                 
 







                                                           
                                                 
                           
                                                                      










                                                                        
 




                                                                  
 




                                                                   
 
                                                                                      
                                 

                                                                 
                                                                   
 
                                                   

                                     
 


                                                          
 


                                                                   
 
                                                    

                                
                                                      
                                       
                                                      



                                             



                                                     
                                                      

                                      
                                                    
                         



                                                                                          





                                                                             















                                                                  
                         
 














                                                                                       
                                                                                            

                                                                    
                                 


                                                         















                                                                              
                                 


                                                                        
                         
 
                                                     

                                             
 
                                                          
 
                                        
 
                                            
 
                                                             
 
                                                                                   
 
                                                                                                               
 
                                                                            
 
                                                                                                                   
 
                                                                                               
 
                                                                                              
 
                                                                                     
 
                                                                                        
 
                                                                           




                                                         
                                         
 
                                 
 

                                             
                                                                                                  
 
                                                     
 
                                                                                                  
 
                                                     
 
                                                                                                
 
                                                                       
 
                                                                                                
 
                                                                       
 
                                                            
 
                                                  
                                                             
                                                                      
                                                                                                                    
                                                                                                                                          
 
                                                                 
 
                                                                    
 
                                                                    
 
                                                                             
 
                                                                                                                                               
 
                                                                     
 
                                                                                          
 
                                                                         
 
                                                                                      
 
                                                                                                                                
                                                 
                                         
                                                                                       
 
                                                                                            
 
                                                 
                                                  
                                                    
                                                             
                                                         

                                                                     
                                                      
                                 
 
                                         
 
                                                           
                                                                                   
 
                                                                                                
 
                                                                                                
 
                                                                                                 
 
                                                                                                 
 
                                                                                          
 
                                                                                             
 
                                                                                   
 
                                                                                                
 
                                                                                                
 
                                                        
 
                                                                                                           
 
                                                               
 
                                                                           
 
                                         
 
                                 
 
                                        
 
                                                 
 
                                             
 
                                                                      
 
                                                                        
 
                                                        
 
                                                           
 
                                         
 
                                                                               
 
                                                                                                  
 
                                                                                               
 
                                         
 
                                                                               
 
                                                           
 
                                         
 





                                                                                           
 
                                                                                                        
 
                                                                                                                                           
 
                                                                         
 
                                                                                                                  
 
                                                                                                                  
 
                                                                                        
 
                                         
 
                                                                                                    
 
                                                                                                                                       
 
                                                                                                             
 
                                                                                                   
 
                                                                                  
 
                                                                                                                  
 
                                                                                                                  
 
                                                                                        
 
                                         
 
                                                                                                                     
 
                                                                            
 
                                         
 
                                                                                                             
 
                                                                                                            
 






                                                                                                                             
                                                                                                         
                                                                                        
                                         
 
                                                                    
 
                                                                       
 
                                                                                   
 
                                                                                      
 
                                                                                         
 
                                                                    
 




                                                                                                                                                   


                                                                                                   
                                                         
                                                 
 




                                                                                                                                
                                                         
                                                 
                                         
 
                                                                      
 



                                                                                                            
                                                                                                                                               
 
                                                                                                                                                 
 
                                                                                                                                                     
 
                                                                                                                                                                                                                                                                  
 
                                                                                                                                                                                                                                                             
 
                                                                                                                                                                                                                                                            
 
                                                                                                                                                                                                                                                       
 
                                                                                       
 
                                                                                  
 
                                                 
 
                                                                                   
 





                                                                                                                                                                                                                   
                                                         


                                                                                                
                                                         
                                                 
                                         
 
                                                                                                              
 
                                                                                      
 
                                                                                                                                                                           
                                                                                                              







                                                                                                                                                    
                                                                                                                 
                                                                                                           
                                                                                                       
                                                                                                                       
                                                                                                                        
                                                                 
                                                         
                                                 
                                         
 
                                                     
 
                                                        
 
                                               
 
                                                                                      
 
                                                                                                                                                                 
 
                                                                                                                                                                             
 
                                                                                                                                                             
 
                                                                                                                                                                         
 
                                                                                                                                                                  
 
                                                                                                                                                                              
 
                                                                                                                                                              
 
                                                                                                                                                                          
 
                                                                                                                                                              
 
                                                                                                                                                                          
 
                                              
 
                                                                                                                                        
 
                                                                                                                                         
 
                                                                                                                                          
 
                                         
 
                                                                                  
                                                                                  
                                                                    
                                                                      
 




                                                                                                 

                                                                                          
 
                                            
                                                         
 
                                                                                                                                    
 
                                                     
 
                                                        
 
                                                           
 
                                                                            
 
                                                                                                                         
 
                                                                                                                             
 
                                         
 
                                                                        
 
                                                                                                                        
 
                                                                                                                              
 
                                         
 
                                                                             
 
                                                                                                                        
 
                                                                                                                             
 
                                         
 
                                                                         
 
                                                                                                                        
 
                                                                                                                             
 
                                         
 
                                                                         
 
                                                                                                                        
 
                                                                                                                             
 
                                         
 


                                                                                       
                                 
 
                                                  
 
                                                   
 
                                               
 
                                                                                                                                                                                        
 
                                                                                                                                                       
 
                                                                                                                                                   
 
                                                                                                                               
 











                                                                           
 




                                                                                                        
 



                                                                                      

                                                                                       
                                 


                         
 
                                                    
 
                                     
 
                                               
 
                                                
 
                                        
                                             
 
                                                                  
 
                                                         
 
                                               
 
                                                
 
                                                
 
                                                                                                                                                                                                                        
 
                                                                                                                                                                                                                     
 
                                                                                                                                                                                                                 
 
                                                                                                                                                                                                                                                                                      
 
                                                                                                                                                                                                                                                                                       
 
                                                                                                                                                                                                                                                                                      
 
                                                                                                                                                                                                                                                                                       
 
                                 
 
                                               
 
                                                              
 
                                                   
 
                                 
 
                                                
 
                                                                    
 
                                                                                                                                                           
 
                                                                                                                                                                
 
                                 
 
                                                                
 
                                                                                                                                                           
 
                                                                                                                                                                
 
                                 
 
                                                                 
 
                                                                                                                                                             
 
                                                                                                                                                                  
 
                                 
 
                                                                 
 
                                                                                                                                                             
 
                                                                                                                                                                  
 
                                 
 
                                                                     
 
                                                                                                                                                           
 
                                                                                                                                                                  
 
                                 
 
                                                   
 

                                             
                                                                                                  
 
                                                     
 
                                                                                                  
 
                                                     
 
                                                                                                
 
                                                                       
 
                                                                                                
 
                                                                       
 
                                                            
 
                                                  
                                                             
                                                                      
                                                                                                                    
                                                                                                                                          
 
                                                                 
 
                                                                    
 
                                                                             


                                                 
                                         
                                                                                       
                                                                                            
 
                                                 
 
                                                    
 
                                                             
 
                                 
 
                                        
 
                                            
 
                                                             
 
                                                                                                                        
 
                                                                                                               
 
                                                                            
 
                                                                                                                   
 
                                                                                               
 
                                                                                              
 
                                                                                     
 
                                                                                        
 
                                                                           






                                                         
                                 
 
                                               
 
                                             
 
                                                                                                       




                         
         
 
         
 
              
                              
                                                           
                                                    
                                               
                                      
                                           

                                                       
                                                                                  
         
 
                                                           
                                                    
                                                 
                                      
                                           

                                                              
                                                                                   
         
 
                           
                                       
                    
                                                  
                                                                                                             
                                 
                                                           
                                                                     
                         
 
                                                                  
                                                                                             
                                                                                             
                                                                                                              
                                                                                                                                                                               
 







                                                                                                                                                                                          
 


                                                                                                      
                                                                                                    




                                                                                          
                                                                                       

                                                                                                     

                                         

                                                                                      
 
                                 
 
                                                            
                                                 


                                                                       
 
                                                                           
                                                                      
                                                                  
                                                                                  
                                                                                         
                                                                                                                                                               
                                                 
 
                                                                                                      
                                                                                                    




                                                                                          
                                                                                       


                                                                                                     


                                         

                                                                                      

                                 
 
                                                                                                           
 
                                                            
 
                                                                     
 
                                                                                                         
 
                                                                                                                                                    
 
                                                                                
 
                                                                         
 

                                                                                                                     
                                                                                                                    




                                                                                                         
 
                                                                                              
 
                                                                                                                                                               
 
                                                                                                                                 
 
                                                                                                                                      
 
                                                                                                  
 
                                                                                             
 


                                                                                                                       

                                                                                                                               
 
                                                                                                                    


                                                                                                                   
                                                                         
 

                                                                                                                          
 




                                                                                                           
                                                                                               
 
                                                                                                                                 
 
                                                                                                                                      
 
                                                                                                    
 




                                                                                                                                                                                                                             
                                                                                 


                                                                                                                       
                                                                                 
                                                                         
                                                                  
                                                                                         
                                                         
                                                 
                                         
                                 
                                                                           
                         
 
                                 
 
                                                           
 
                                                                     
 
                                                                                          
                                                                
                                                                                                                       
                                                                                                                            
 






                                                                                    
                                                                                                 
                                                                                
 
                                                     
 
                                                                                                                   
 
                                                                 
 
                                                                              
                                                                  
                                                                               
                                                                   
                                                                                                             
                                                                                                             
                                                                                                                              
 
 
                                                         
 
                                                                                                                                                     
 
                                                                                 
                                                                
 
                                                                                                                                                                            
 
                                                 
 
                                                                 
                                                                                 
                                                                   
                                                                  
                                                                                                                                              
                                                 
                                           
 
                                                                     
 
                                                                                                                            
 
                                                                                                                                                                                                                                                
 
                                                                               
 
                                                                                           
 
                                                                                        
 
                                                                          
 
                                                                              
 
                                                                                                                                                                                                                                                                            
 
                                                                              
 
                                                                             
 
                                                 
 
                                                                          

                                                                         
 

                                                                                                     
 





                                                                                                                                    


                                                                                           
                                                  
 
                                                                     










                                                                                                                          
                                                                                               


                                                                                                                                                             
                                                                                            
                                                                                        
                                                                                       
                                                         
                                                 
                                                 
                                                 
                                         
                                 
                         
                 
         
 


                                       
 

                         
 
                                                                                                                                                                  
 
                                                                      
 
                                                                                                                                              
 
                                                                              
 
                    
 
                                                     
 



                                            
 






                                                                           
                         
 
                                                     
                                                                     

                                                                       
                         
                                                  
                 

                                                     
 


                                            














                                                                         
                 
         
 


                                           
                                  

                          
 
// Game tick handling
// Copyright (C) 2002  David Rosen
// Copyright (C) 2003  Ryan C. Gordon
// Copyright (C) 2003  Dan Olson
// Copyright (C) 2003  Steven Fuller
// Copyright (C) 2003  Zachary Jack Slater
// Copyright (C) 2003  Toby Haynes
// Copyright (C) 2021-2022  Nguyễn Gia Phong
//
// This file is part of Black Shades.
//
// Black Shades is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Black Shades is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Black Shades.  If not, see <https://www.gnu.org/licenses/>.

#include <algorithm>

#include "Game.h"
#include "misc.h"

extern float multiplier;
extern int thirdperson;
extern int visions;
extern Sprites sprites;
extern unsigned int gSourceID[37];
extern Camera camera;
extern float camerashake;
extern Fog fog;
extern int environment;
extern float precipitationhorz;
extern float precipitationvert;
extern float snowdelay;
extern float precipitationdensity;
extern float soundscalefactor;
extern int slomo;
extern Decals decals;

#define maxfallvel 40

void Splat(Game* game, int k)
{
	if (k && visions)
		return;

	auto& person = game->person[k];
	if (person.velocity.y > -maxfallvel) {
		person.velocity.y = 0;
		return;
	}

	auto& skeleton = person.skeleton;
	skeleton.free = 1;
	skeleton.offset = 0;
	person.health = 0;
	person.longdead = person.bleeding = person.bleeddelay = 1;
	person.DoAnimations(k);

	auto& joints = skeleton.joints;
	auto& head_joint = joints[head];
	person.bjoint1 = &head_joint;
	person.bjoint2 = joints + neck;

	for (auto& joint : joints) {
		joint.position = DoRotation(joint.position + joint.offset, 0,
			person.playerrotation, 0) + person.playercoords;
		joint.realoldposition = joint.position;
		joint.velocity = {0, person.velocity.y, 0};
	}

	auto soundpos = head_joint.position - camera.position;
	ALfloat gLoc[] {
		soundpos.x / soundscalefactor,
		soundpos.y / soundscalefactor,
		soundpos.z / soundscalefactor,
	};
	alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
	alSourcePlay(gSourceID[headwhacksound]);
}

void updateSong(Game* game)
{
	if (environment == rainy_environment)
		alSourcePlay(gSourceID[rainsound]);
	else
		alSourcePause(gSourceID[rainsound]);

	alSourceStop(gSourceID[game->whichsong]);
	alSourcef(gSourceID[game->whichsong], AL_MIN_GAIN, 0);
	alSourcef(gSourceID[game->whichsong], AL_MAX_GAIN, 0);

	if (game->type == zombie_type)
		game->whichsong = zombiesong;
	else if (game->person[0].whichgun == knife)
		game->whichsong = knifesong;
	else
		game->whichsong = shootsong;

	alSourcef(gSourceID[game->whichsong], AL_PITCH, 1);
	alSourcef(gSourceID[game->whichsong], AL_MIN_GAIN, 1);
	alSourcef(gSourceID[game->whichsong], AL_MAX_GAIN, 1);
	alSourcePlay(gSourceID[game->whichsong]);
}

void click(Game* game, int button, int action, int mods)
{
	if (game->menu) {
		if (button != GLFW_MOUSE_BUTTON_LEFT)
			return;
		double xpos, ypos;
		auto window = glfwGetCurrentContext();
		glfwGetCursorPos(window, &xpos, &ypos);
		double mousex = xpos * 640 / game->screenwidth;
		double mousey = 480 - ypos * 480 / game->screenheight;

		auto button = 0;
		if (mousex > 120 && mousex < 560) {
			if (mousey > 235 && mousey < 305)
				button = 1;
			else if (mousey > 112 && mousey < 182)
				button = 2;
		}
		if (action == GLFW_PRESS) {
			game->mouseoverbutton = button;
			return;
		} else if (button != game->mouseoverbutton) {
			game->mouseoverbutton = 0;
		}

		switch (game->mouseoverbutton) {
		case 1:
			updateSong(game);
			game->flashr = game->flashg = game->flashb = 1.0f;
			game->flashamount = 1.0f;
			alSourcePlay(gSourceID[soulinsound]);

			if (!game->gameinprogress) {
				game->mission = 0;
				initGame(game);
			}

			if (visions)
				alSourcePlay(gSourceID[visionsound]);

			game->gameinprogress = true;
			setMenu(game, false);
			break;
		case 2:
			if (game->gameinprogress) {
				game->flashr = game->flashg = game->flashb = 1.0f;
				game->flashamount = 1.0f;
				game->gameinprogress = false;
			} else {
				game->flashamount = game->flashr = 1.0f;
				game->flashg = game->flashb = 0.0f;
				glfwSetWindowShouldClose(window, true);
			}

			alSourcePlay(gSourceID[losesound]);
			break;
		}
		game->mouseoverbutton = 0;
		return;
	}

	auto& player = game->person[0];
	auto& weapon = player.whichgun;

	if (visions) {
		if (action == GLFW_PRESS)
			alSourcePlay(gSourceID[soulinsound]);
		return;
	}

	XYZ facing {0, 0, -1};
	facing = DoRotation(facing, -camera.rotation2, 0, 0);
	facing = DoRotation(facing, 0, -camera.rotation, 0);

	XYZ flatfacing = facing;
	flatfacing.y = 0;
	Normalise(&flatfacing);

	// Gun whacking or knife slashing
	if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS
	    && player.attackframe < 0
	    && (!player.aiming || player.ammo <= 0
	        || weapon == nogun || weapon == knife
	        || player.targetanimation == joganim)
	    && player.targetanimation != diveanim
	    && player.targetanimation != throwanim) {
		bool attacking = false;
		float closedistance = 0.0f;
		for (int i = 1; i < game->numpeople; ++i) {
			auto& person = game->person[i];
			if (person.type == viptype || person.skeleton.free)
				continue;
			auto distance = findDistancefast(person.playercoords,
				player.playercoords + flatfacing);
			if (distance > 12 + (weapon == knife) * 10)
				continue;
			if (closedistance == 0 || distance < closedistance) {
				attacking = true;
				player.killtarget = i;
				closedistance = distance;
			}
		}

		if (attacking) {
			player.attacktarget = 0;
			player.attackframe = 0;
			game->whacked = false;
			return;
		}
	}

	// Disarming
	if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS
	    && player.attackframe < 0
	    && (!player.aiming || weapon == nogun || weapon == knife)
	    && (player.targetanimation == idleanim
	        || player.targetanimation == walkanim
	        || player.targetanimation == joganim)) {
		bool attacking = false;
		float closedistance = 0.0f;
		for (int i = 1; i < game->numpeople; ++i) {
			auto& person = game->person[i];
			if (person.skeleton.free || person.whichgun == nogun)
				continue;
			auto distance = findDistancefast(person.playercoords,
				player.playercoords + flatfacing);
			if (distance > 12)
				continue;
			attacking = true;
			if (closedistance == 0 || distance < closedistance) {
				player.killtarget = i;
				closedistance = distance;
			}
		}

		if (attacking) {
			auto& target = game->person[player.killtarget];
			weapon = target.whichgun;
			player.ammo = target.ammo;
			player.aiming = true;
			target.whichgun = nogun;
			target.killtarget = -1;

			target.targetframe = player.targetframe = 0;
			target.targetanimation = player.targetanimation = throwanim;
			target.target = player.target = 1;
			target.playercoords = player.playercoords;
			target.playerrotation = player.playerrotation;
			target.speed = player.speed = 1;
			target.speedmult = 1;
			game->score += 150;
			return;
		}
	}

	// Pulling gun trigger
	if (player.aiming && player.targetanimation != joganim
	    && weapon != nogun && weapon != knife && weapon != grenade) {
		if (button == GLFW_MOUSE_BUTTON_RIGHT && weapon == sniperrifle)
			game->zoom = action == GLFW_PRESS;
		else if (button == GLFW_MOUSE_BUTTON_LEFT)
			player.firing = action == GLFW_PRESS;
		else if (button == GLFW_MOUSE_BUTTON_MIDDLE && game->debug)
			player.firing = player.grenphase = action == GLFW_PRESS;
		return;
	}

	// Grenade
	if (weapon == grenade && player.ammo > 0
	    && player.reloading <= 0 && player.attackframe < 0) {
		auto& skeleton = player.skeleton;
		auto& hand = skeleton.joints[righthand];
		auto soundsrc = DoRotation(hand.position, 0, player.playerrotation, 0)
			+ player.playercoords - camera.position;
		if (player.grenphase) {
			if (button == GLFW_MOUSE_BUTTON_LEFT
			    && action == GLFW_RELEASE) { // throw
				player.grenphase = false;
				player.attackframe = 0;
				player.attacktarget = 0;
				player.killtarget = 0;
			} else if (button == GLFW_MOUSE_BUTTON_RIGHT
			           && action == GLFW_PRESS) { // put pin back
				player.grenphase = false;
				playSound(gSourceID[pinreplacesound],
					soundsrc.x, soundsrc.y, soundsrc.z);
			}
		} else {
			if (button == GLFW_MOUSE_BUTTON_LEFT
			    && action == GLFW_PRESS) { // pull pin
				player.grenphase = true;
				playSound(gSourceID[pinpullsound],
					soundsrc.x, soundsrc.y, soundsrc.z);
			}
		}
	}
}

void look(Game* game, double xpos, double ypos)
{
	if (game->menu)
		return;

	int width, height;
	const auto window = glfwGetCurrentContext();
	glfwGetWindowSize(window, &width, &height);
	int xcenter = width / 2, ycenter = height / 2;
	glfwSetCursorPos(window, xcenter, ycenter); // we shouldn't need this

	auto& player = game->person[0];
	auto factor = game->mouse_sensitivity;
	if (player.aimamount >= 1)
		factor *= (game->zoom) ? 0.05 : 0.8;
	if (slomo == 2)
		factor *= 0.6;

	camera.rotation += (xpos - xcenter) * factor;
	camera.rotation2 += (ypos - ycenter) * factor;

	// Smoothen camera movements
	camera.rotation = camera.rotation * 0.7 + camera.oldrotation * 0.3;
	camera.oldrotation = camera.rotation;
	player.playerrotation = 180 - camera.rotation;

	camera.rotation2 = camera.rotation2 * 0.7 + camera.oldrotation2 * 0.3;
	camera.rotation2 = std::min(std::max(camera.rotation2, -89.0f), 89.0f);
	camera.oldrotation2 = camera.rotation2;

	if (game->zoom || visions || player.aimamount <= 0
	    || player.whichgun == nogun
	    || player.whichgun == grenade
	    || player.whichgun == knife) {
		camera.visrotation = camera.rotation;
		camera.visrotation2 = camera.rotation2;
	} else {
		camera.visrotation = std::min(camera.rotation + 7,
			std::max(camera.rotation - 7, camera.visrotation));
		camera.visrotation2 = std::min(camera.rotation2 + 15,
			std::max(camera.rotation2 - 15, camera.visrotation2));
	}
}

void setListener(Game* game, XYZ facing)
{
	XYZ upvector {0, 0, -1};
	upvector = DoRotation(upvector, -camera.rotation2 + 90, 0, 0);
	upvector = DoRotation(upvector, 0, -camera.rotation, 0);

	ALfloat ori[] {
		facing.x, facing.y, facing.z,
		-upvector.x, upvector.y, upvector.z,
	};
	alListenerfv(AL_ORIENTATION, ori);
}

XYZ aimPlayer(Game* game)
{
	auto& joints = game->person[0].skeleton.joints;
	auto point = joints[lefthand].position - joints[righthand].position;
	float aimrot = 0.0f, aimrot2 = 0.0f;

	switch (game->person[0].whichgun) {
		case assaultrifle:
			aimrot = -2.5f;
			break;
		case sniperrifle:
			aimrot = 4.0f;
			break;
		case shotgun:
			aimrot = randInt(-1000, 1000) / 500.0f - 1;
			aimrot2 = randInt(-1000, 1000) / 500.0f + 2;
			break;
		case handgun1:
		case handgun2:
			aimrot = -0.9f;
			auto k = thirdperson ? 0.35 : 0.65;
			point = joints[righthand].position
				- joints[head].position * k
				- joints[neck].position * (1 - k);
		break;
	}

	return DoRotation(point, aimrot2,
		game->person[0].playerrotation + aimrot, 0);
}

XYZ aimBot(Game* game, int j)
{
	auto& bot = game->person[j];
	float inaccuracy = 0.0f;
	switch (bot.whichgun) {
	case handgun1:
	case handgun2:
		inaccuracy = 8.0f;
		break;
	case assaultrifle:
	case shotgun:
		inaccuracy = 6.0f;
		break;
	case sniperrifle:
		inaccuracy = 2.0f;
		break;
	}

	auto& target = game->person[bot.killtarget];
	if (target.skeleton.free)
		inaccuracy *= 3;

	auto& joints = target.skeleton.joints;
	XYZ aim = joints[abdomen].position;
	if (target.skeleton.free)
		inaccuracy *= 3;
	else
		aim = DoRotation(aim, 0, target.playerrotation, 0)
			+ target.playercoords;

	auto& lefthandpos = joints[lefthand].position;
	aim -= bot.playercoords
		+ DoRotation(lefthandpos, 0, bot.playerrotation, 0);
	return DoRotation(
		DoRotation(DoRotation(aim, 0, -bot.playerrotation, 0),
			randFloat() * inaccuracy, randFloat() * inaccuracy, 0),
		0, bot.playerrotation, 0);
}

void nextLevel(Game* game)
{
	game->score += ++game->mission * 50 + 100;
	game->highscore = std::max(game->score, game->highscore);

	game->flashamount = game->flashg = 1;
	game->flashr = game->flashb = 0;
	alSourcePlay(gSourceID[souloutsound]);

	if (game->mission >= game->nummissions) {
		alSourcePause(gSourceID[rainsound]);
		alSourceStop(gSourceID[visionsound]);
		alSourceStop(gSourceID[game->whichsong]);
		alSourcef(gSourceID[game->whichsong], AL_MIN_GAIN, 0);
		alSourcef(gSourceID[game->whichsong], AL_MAX_GAIN, 0);

		game->whichsong = mainmenusong;
		alSourcef(gSourceID[game->whichsong], AL_PITCH, 1);
		alSourcef(gSourceID[game->whichsong], AL_MIN_GAIN, 1);
		alSourcef(gSourceID[game->whichsong], AL_MAX_GAIN, 1);
		alSourcePlay(gSourceID[game->whichsong]);

		setMenu(game, game->beatgame = true);
		game->gameinprogress = 0;
	} else {
		updateSong(game);
		initGame(game);
	}
}

void checkPersonCollisions(Game* game, int k)
{
	auto& person = game->person[k];
	person.oldplayercoords = person.playercoords;
	person.DoStuff(k);
	if (person.skeleton.free)
		return;

	person.onground = false;
	auto overpoint = person.playercoords;
	overpoint.y += 3000;
	auto underpoint = person.playercoords;
	underpoint.y -= 3000;

	const int x = (person.playercoords.x + block_spacing / 2) / block_spacing;
	const int z = (person.playercoords.z + block_spacing / 2) / block_spacing;
	const int endx = std::min(num_blocks - 1, x + 1);
	const int endz = std::min(num_blocks - 1, z + 1);
	/* TODO: huh?
	 * if(k!=0) {
	 * 	beginx == person.whichblockx;
	 * 	beginz == person.whichblocky;
	 * 	endx == person.whichblockx;
	 * 	endz == person.whichblocky;
	 * }
	 */

	for (auto i = std::max(0, x); i <= endx; ++i)
		for (auto j = std::max(0, z); j <= endz; ++j) {
			// Ground collision
			const auto city_rot = game->cityrotation[i][j] * 90;
			const XYZ move = {(float) i * block_spacing,
				0.0f, (float) j * block_spacing};
			XYZ collpoint;
			if (game->sidewalkcollide.LineCheck2(overpoint,
					underpoint, &collpoint, move, city_rot) == -1)
				continue;

			if (person.playercoords.y <= collpoint.y
			    && person.velocity.y <= 0) {
				person.playercoords.y = collpoint.y;
				person.onground = true;
				Splat(game, k);
			}

			if (k != 0)
				continue;
			game->onblockx = i;
			game->onblocky = j;

			// Wall collision
			float depth;
			const auto city_type = game->citytype[i][j];
			for (auto& bound : game->boundingpoints) {
				const auto whichtri = game->blockwalls[city_type].LineCheck3(person.playercoords + bound,
					person.playercoords + bound,
					&collpoint, move, city_rot, &depth);
				if (whichtri == -1)
					continue;
			}
			for (auto& bound : game->boundingpoints) {
				auto pointnum = k + 1;
				if (pointnum > 3)
					pointnum = 0;
				const auto whichtri = game->blockwalls[city_type].LineCheck3(person.playercoords + bound,
					person.playercoords + game->boundingpoints[pointnum],
					&collpoint, move, city_rot, &depth);
				if (whichtri == -1)
					continue;
				person.playercoords += DoRotation(game->blockwalls[city_type].normals[whichtri], 0, city_rot, 0);
			}
		}

	if (person.playercoords.y <= 0) {
		person.onground = true;
		person.playercoords.y = 0;
		Splat(game, k);
		if (k == 0)
			game->onblockx = game->onblocky = -1;
	}
}

void Game::Tick()
{
	if (person[1].health <= 0 || person[0].health <= 0 || killedinnocent)
		losedelay -= multiplier / 6;
	else
		timeremaining -= multiplier;

	if (timeremaining <= 0)
		nextLevel(this);

	if (losedelay <= 0) {
		score -= (person[murderer].health > 0) ? 200 : 100;

		flashamount = 1;
		flashr = flashg = flashb = 0;
		alSourcePlay(gSourceID[soulinsound]);

		updateSong(this);
		initGame(this);
	}

	sprites.DoStuff();
	decals.DoStuff();

	// Facing
	XYZ facing {0, 0, -1};
	facing = DoRotation(facing, -camera.rotation2, 0, 0);
	facing = DoRotation(facing, 0, -camera.rotation, 0);

	XYZ flatfacing = facing;
	flatfacing.y = 0;
	Normalise(&flatfacing);

	// Check collision with buildings
	int beginx,endx;
	int beginz,endz;
	XYZ move;
	int whichtri;
	XYZ underpoint;
	XYZ overpoint;
	for (auto k = numpeople; k--; checkPersonCollisions(this, k));

	// Camera
	camera.oldposition = camera.position;
	camera.targetoffset = {0.0f, 0.0f, -5.0f};

	// Spawn people
	int cyclenum = 0;
	int blockspawnx = 0, blockspawny = 0;
	do {
		auto block = person[0].playercoords / block_spacing;
		blockspawnx = block.x + 0.5f + randInt(-1, 1);
		blockspawny = block.z + 0.5f + randInt(-1, 1);

		auto& people = citypeoplenum[blockspawnx][blockspawny];
		if (people < max_people_block)
			break;
	} while (++cyclenum < 10);

	spawndelay -= multiplier;
	if(cyclenum<10){

	if (spawndelay < 0 && numpeople < max_people) {
		if (type == zombie_type)
			person[numpeople].type = zombietype;
		else if (randUint(evilprobability))
			person[numpeople].type = civiliantype;
		else
			person[numpeople].type = eviltype;

		if(person[numpeople].type!=civiliantype&&blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky){
			while((citypeoplenum[blockspawnx][blockspawny]>=max_people_block&&cyclenum<10)||blockspawnx==0||(blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky)){
				blockspawnx = (person[0].playercoords.x + block_spacing / 2) / block_spacing + randInt(-1, 1);
				blockspawny = (person[0].playercoords.z + block_spacing / 2) / block_spacing + randInt(-1, 1);
				cyclenum++;
			}
		}

		person[numpeople].playerrotation=0;
		person[numpeople].whichcostume = casualcostumes + randUint(numcasual);
		person[numpeople].whichblockx=blockspawnx;
		person[numpeople].whichblocky=blockspawny;
		person[numpeople].pathnum=-1;
		person[numpeople].oldpathnum=-1;
		person[numpeople].oldoldpathnum=-1;
		person[numpeople].oldoldoldpathnum=-1;

		while(person[numpeople].pathnum<0||person[numpeople].pathnum>=path.vertexNum||person[numpeople].pathnum==1){

			person[numpeople].pathnum = randUint(path.vertexNum);

		}

		person[numpeople].pathtarget.x=path.vertex[person[numpeople].pathnum].x;

		person[numpeople].pathtarget.z=path.vertex[person[numpeople].pathnum].z;

		person[numpeople].pathsize = 0.98f + 0.04f * randFloat();

		person[numpeople].pathtarget*=person[numpeople].pathsize;

		person[numpeople].pathtarget.x+=person[numpeople].whichblockx*block_spacing;

		person[numpeople].pathtarget.z+=person[numpeople].whichblocky*block_spacing;

		person[numpeople].playercoords=person[numpeople].pathtarget;

		person[numpeople].oldplayercoords=person[numpeople].playercoords;

		person[numpeople].skeleton.free=0;

		person[numpeople].targetanimation=walkanim;

		if(person[numpeople].type==zombietype)person[numpeople].targetanimation=zombiewalkanim;

		person[numpeople].speed=1;

		person[numpeople].existing=0;

		person[numpeople].speedmult = 0.8f + 0.4f * randFloat();

		person[numpeople].health=100;

		person[numpeople].maxhealth=100;

		person[numpeople].playerrotation2=0;

		person[numpeople].lastdistancevictim=200000;

		if(numpeople==1)person[numpeople].type=viptype;

		person[numpeople].killtarget=-1;

		if(person[numpeople].type==eviltype){person[numpeople].existing=1; person[numpeople].pathsize=1.04; person[numpeople].whichgun=nogun; person[numpeople].aiming=1; person[numpeople].killtarget=-1; person[numpeople].speedmult=1+.3*difficulty;}

		if(person[numpeople].type==zombietype){person[numpeople].existing=1; person[numpeople].pathsize=1.04; person[numpeople].whichgun=nogun; person[numpeople].aiming=0; person[numpeople].killtarget=-1; person[numpeople].speedmult=0.7+.2*difficulty;}

		else {person[numpeople].whichgun=nogun; person[numpeople].aiming=0; person[numpeople].killtarget=-1;}

		if(person[numpeople].type==viptype){person[numpeople].existing=1;}

		if(enemystate==2)person[numpeople].killtarget=1;

		numpeople++;

		citypeoplenum[blockspawnx][blockspawny]++;

		spawndelay=.1;

	}

	if(spawndelay<0&&numpeople>=max_people){

		if(cycle>=max_people)cycle=0;

		cyclenum=0;

		while(cyclenum<max_people&&(person[cycle].type==playertype||person[cycle].type==viptype||(abs(person[cycle].whichblockx-((person[0].playercoords.x+block_spacing/2)/block_spacing))<2&&abs(person[cycle].whichblocky-((person[0].playercoords.z+block_spacing/2)/block_spacing))<2))){

			cycle++;

			cyclenum++;

			if(cycle>=max_people)cycle=0;

		}

		if(cycle<max_people&&cyclenum<max_people){
			if (type == zombie_type)
				person[cycle].type = zombietype;
			else if (randUint(evilprobability))
				person[cycle].type = civiliantype;
			else
				person[cycle].type = eviltype;

			if(person[cycle].type!=civiliantype&&blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky){
				while((citypeoplenum[blockspawnx][blockspawny]>=max_people_block&&cyclenum<10)||blockspawnx==0||(blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky)){
					blockspawnx = (person[0].playercoords.x + block_spacing / 2) / block_spacing + randInt(-1, 1);
					blockspawny = (person[0].playercoords.z + block_spacing / 2) / block_spacing + randInt(-1, 1);
					cyclenum++;
				}
			}

			person[cycle].playerrotation=0;
			person[cycle].whichcostume = casualcostumes + randUint(numcasual);
			citypeoplenum[person[cycle].whichblockx][person[cycle].whichblocky]--;
			person[cycle].whichblockx=blockspawnx;
			person[cycle].whichblocky=blockspawny;
			person[cycle].pathnum=-1;
			person[cycle].oldpathnum=-1;
			person[cycle].oldoldpathnum=-1;
			person[cycle].oldoldoldpathnum=-1;

			while(person[cycle].pathnum<0||person[cycle].pathnum>=path.vertexNum||person[cycle].pathnum==1){
				person[cycle].pathnum = randUint(path.vertexNum);
			}

			person[cycle].pathtarget.x=path.vertex[person[cycle].pathnum].x;

			person[cycle].pathtarget.z=path.vertex[person[cycle].pathnum].z;

			person[cycle].pathsize= 0.98f + 0.04f * randFloat();

			person[cycle].pathtarget*=person[cycle].pathsize;

			person[cycle].pathtarget.x+=person[cycle].whichblockx*block_spacing;

			person[cycle].pathtarget.z+=person[cycle].whichblocky*block_spacing;

			person[cycle].playercoords=person[cycle].pathtarget;

			person[cycle].oldplayercoords=person[cycle].playercoords;

			person[cycle].skeleton.free=0;

			person[cycle].targetanimation=walkanim;

			if(person[cycle].type==zombietype)person[cycle].targetanimation=zombiewalkanim;

			person[cycle].speed=1;

			person[cycle].existing=0;

			person[cycle].speedmult = 0.8f + 0.4f * randFloat();

			person[cycle].health=100;

			person[cycle].maxhealth=100;

			person[cycle].playerrotation2=0;

			if(enemystate==1)person[cycle].killtarget=-1;

			if(person[cycle].type==eviltype){person[cycle].existing=1;  person[cycle].pathsize=1.04; person[cycle].whichgun=nogun; person[cycle].aiming=1; person[cycle].killtarget=-1; person[cycle].speedmult=1+.3*difficulty;}

			if(person[cycle].type==zombietype){person[cycle].existing=1; person[cycle].pathsize=1.04; person[cycle].whichgun=nogun; person[cycle].aiming=0; person[cycle].killtarget=-1; person[cycle].speedmult=.7+.2*difficulty;}

			else {person[cycle].whichgun=nogun; person[cycle].aiming=0; person[cycle].killtarget=-1;}

			person[cycle].lastdistancevictim=200000;

			if(enemystate==2)person[cycle].killtarget=1;

			if(numpeople<max_people)numpeople++;

			citypeoplenum[blockspawnx][blockspawny]++;

			cycle++;

			spawndelay=.1;

		}

	}}

	XYZ towards;
	XYZ finaltarget;
	XYZ blah;
	int closesttarget = 0;
	float leastdistance = 0.0;
	XYZ bleedloc;
	XYZ vel;
	float tooclose;
	float toofar;

	//People
	for(int i=0;i<numpeople;i++){
		if(person[i].health<0&&person[i].longdead<0&&person[i].firstlongdead==0){
			if(person[i].type!=zombietype){
				overpoint=person[i].skeleton.joints[abdomen].position;
				overpoint.y+=3000;
				underpoint=person[i].skeleton.joints[abdomen].position;
				underpoint.y-=3000;

				move = {
					(float) person[i].whichblockx * block_spacing,
					0.0f,
					(float) person[i].whichblocky * block_spacing,
				};

				XYZ temp;
				whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&temp,move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);

				XYZ normish {0.0f, 1.0f, 0.0f};
				if(whichtri>=0){
					decals.MakeDecal(bloodpool,temp,12,normish, whichtri, &sidewalkcollide, move, cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
				}
				if(whichtri==-1){
					temp=person[i].skeleton.joints[abdomen].position;
					temp.y=-.5;
					move = {};
					decals.MakeDecal(bloodpool,temp,12,normish, 0, &sidewalkcollide, move, 0);
				}

				person[i].firstlongdead=1;

			}

		}

		if(person[i].health<100&&person[i].type!=zombietype){
				person[i].health-=multiplier*120;
		}

		if(person[i].health<100&&person[i].type==zombietype){
				person[i].health+=multiplier*10;
				if(person[i].health>person[i].maxhealth)person[i].health=person[i].maxhealth;
		}

		if(person[i].health<100&&person[i].type==zombietype&&person[i].skeleton.free==1){
				person[i].health+=multiplier*10;
				if(person[i].health>person[i].maxhealth)person[i].health=person[i].maxhealth;
		}

		if(person[i].health<40&&person[i].type==zombietype){
				person[i].speedmult-=multiplier/20;
				if(person[i].speedmult<.6){
					person[i].speedmult=.6;
					person[i].killtarget=-1;
				}
		}

		if(person[i].health>=40&&person[i].type==zombietype){
				person[i].speedmult+=multiplier/40;
				if(person[i].speedmult>.7+difficulty*.2){
					person[i].speedmult=.7+difficulty*.2;
					person[i].killtarget=1;
				}
		}

		if(person[i].maxhealth<100&&person[i].type==zombietype){
				person[i].maxhealth+=multiplier*2;
				if(person[i].maxhealth>100)person[i].maxhealth=100;
		}

		if(person[i].bleeding>0){
			person[i].bleeding-=multiplier;
			person[i].bleeddelay-=multiplier*10;
			if(person[i].bleeddelay<=0){
				person[i].bleeddelay=1;
				if(person[i].skeleton.free==0){
					bleedloc=DoRotation((person[i].bjoint1->position+person[i].bjoint2->position)/2,0,person[i].playerrotation,0)+person[i].playercoords;
				}
				if(person[i].skeleton.free>0){
					bleedloc=(person[i].bjoint1->position+person[i].bjoint2->position)/2;
				}
				vel = {};
				sprites.MakeSprite(bloodspritedown, .6, 1, .2, .2,bleedloc, vel, 3*person[i].bleeding);
			}

		}

		if (!person[i].skeleton.free) {
			// Gun
			switch (person[i].type) {
			case playertype:
				switch (person[i].whichgun) {
				case shotgun:
					person[i].recoil -= multiplier * 4;
					break;
				case sniperrifle:
					person[i].recoil -= multiplier * 2;
					break;
				case handgun1:
				case handgun2:
					person[i].recoil -= multiplier * 5;
					break;
				case assaultrifle:
					person[i].recoil-=multiplier * 10;
					break;
				}
				if (!person[0].aiming || visions)
					this->zoom = false;
				break;
			case eviltype:
				switch (person[i].whichgun) {
				case shotgun:
				case sniperrifle:
					person[i].recoil -= multiplier * 1;
					break;
				case handgun1:
				case handgun2:
					person[i].recoil -= multiplier * 2;
					break;
				case assaultrifle:
					person[i].recoil-=multiplier * 10;
					break;
				}
				break;
			}
			if (person[i].recoil < 0)
				person[i].recoil = 0;

			//Zombie eat
			if(i > 0
			   && person[i].targetanimation == zombieeatanim
			   && person[person[i].killtarget].eaten == i) {
				person[person[i].killtarget].skeleton.joints[head].locked=1;
				person[person[i].killtarget].skeleton.joints[rightshoulder].locked=1;

				for(int k=0;k<2;k++){
					person[person[i].killtarget].skeleton.joints[head].position=DoRotation(person[i].skeleton.joints[righthand].position,0,person[i].playerrotation,0)+person[i].playercoords;
					person[person[i].killtarget].skeleton.joints[head].velocity = {};
					person[person[i].killtarget].skeleton.joints[rightshoulder].position=DoRotation(person[i].skeleton.joints[lefthand].position,0,person[i].playerrotation,0)+person[i].playercoords;
					person[person[i].killtarget].skeleton.joints[rightshoulder].velocity = {};
					person[person[i].killtarget].skeleton.DoConstraints();
					person[person[i].killtarget].skeleton.DoConstraints(&blocksimplecollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
				}

				person[person[i].killtarget].skeleton.joints[head].locked=0;
				person[person[i].killtarget].skeleton.joints[rightshoulder].locked=0;
				person[person[i].killtarget].longdead=1;
			}

			if(i>0&&enemystate!=1&&person[i].type==zombietype&&person[i].speedmult>.7){
				if(findDistancefast(person[i].playercoords,person[1].playercoords)<20000)person[i].killtarget=1;
				else person[i].killtarget=-1;
			}

			if(i>0&&enemystate!=1&&person[i].type==zombietype&&person[i].speedmult<.7){
				person[i].killtarget=-1;
			}

			bool realcheck = false;

			// Pathfinding
			if (i > 0 && person[i].targetanimation != getupfrontanim
			    && person[i].targetanimation != thrownanim
			    && person[i].targetanimation != getupbackanim
			    && person[i].currentanimation != getupfrontanim
			    && person[i].currentanimation != getupbackanim) {
				person[i].pathcheckdelay -= multiplier;
				// Realcheck tells us
				// a) we've got close to the end of our path or
				// b) we're moving away from our target
				auto moving_away
					= findDistancefast(person[i].pathtarget,
						person[i].playercoords)
					> findDistancefast(person[i].pathtarget,
						person[i].oldplayercoords);
				realcheck = (abs(person[i].playercoords.x
						- person[i].pathtarget.x) < 1
					&& abs(person[i].playercoords.z
						- person[i].pathtarget.z) < 1)
					|| moving_away;

				if(person[i].targetanimation==idleanim&&person[i].killtargetvisible==0){
					person[i].targetanimation=walkanim;
					if(person[i].type==zombietype)person[i].targetanimation=zombiewalkanim;
					realcheck=1;
				}

				if((realcheck||((person[i].killtarget>-1&&person[i].type!=civiliantype)&&person[i].pathcheckdelay<=0)||person[i].killtargetvisible)){
					person[i].pathcheckdelay = 1.2f;

					if ((person[i].killtarget == -1
					     || person[i].type == civiliantype)
					    && !person[i].running) {
						person[i].killtargetvisible = 0;
						leastdistance = 2000000;
						for (int j = 0; j < path.vertexNum; j++) {
							person[i].pathtarget.x = path.vertex[j].x;
							person[i].pathtarget.z = path.vertex[j].z;
							person[i].pathtarget.y = path.vertex[j].y;
							person[i].pathtarget *= person[i].pathsize;
							person[i].pathtarget.x += person[i].whichblockx*block_spacing;
							person[i].pathtarget.z += person[i].whichblocky*block_spacing;

							if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&j!=1&&j!=person[i].oldpathnum&&j!=person[i].oldoldpathnum&&j!=person[i].oldoldoldpathnum){
								leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
								closesttarget=j;
							}
						}

						if (closesttarget >= 0 && closesttarget < path.vertexNum) {
							person[i].oldoldoldpathnum = person[i].oldoldpathnum;
							person[i].oldoldpathnum = person[i].oldpathnum;
							person[i].oldpathnum = person[i].pathnum;
							person[i].pathnum = closesttarget;
							person[i].pathtarget.x = path.vertex[person[i].pathnum].x;
							person[i].pathtarget.z = path.vertex[person[i].pathnum].z;
							person[i].pathtarget *= person[i].pathsize;
							person[i].pathtarget.x += person[i].whichblockx*block_spacing;
							person[i].pathtarget.z += person[i].whichblocky*block_spacing;
						}
					}

					if(person[i].running&&realcheck){
						person[i].killtargetvisible=0;
						person[i].targetanimation=joganim;

						// Dead target?
						if (person[person[i].killtarget].health <= 0)
							person[i].running = 0;

						 person[i].killtarget=1;

						// If pathfind
						if (realcheck) {
						leastdistance = 2000000;
						person[i].lastdistancevictim = 0;
						closesttarget = -1;

						// Check best path
						closesttarget = person[i].pathnum;

						// Check other blocks?
						if (closesttarget == person[i].pathnum) {
							beginx = person[i].whichblockx-2;
							if(beginx<0)beginx=0;
							beginz=person[i].whichblocky-2;
							if(beginz<0)beginz=0;
							endx=person[i].whichblockx+2;
							if(endx>num_blocks-1)endx=num_blocks-1;
							endz=person[i].whichblocky+2;
							if(endz>num_blocks-1)endz=num_blocks-1;
							leastdistance=2000000;

							for (int l = beginx; l <= endx; l++) {
								for (int m = beginx; m <= endx; m++) {
									for (int j = 0; j < path.vertexNum; j++){
										person[i].pathtarget.x = path.vertex[j].x;
										person[i].pathtarget.y = path.vertex[j].y;
										person[i].pathtarget.z = path.vertex[j].z;
										person[i].pathtarget*=person[i].pathsize;
										person[i].pathtarget.x+=l*block_spacing;
										person[i].pathtarget.z+=m*block_spacing;

										if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)>findDistancefast(person[i].playercoords,person[person[i].killtarget].playercoords)&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[l][m])==-1){
											person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
											leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
											closesttarget=j;
											finaltarget=person[i].pathtarget;
											person[i].whichblockx=l;
											person[i].whichblocky=m;
										}
									}
									}
								}
							}

						if (closesttarget != -1) {
							person[i].pathnum = closesttarget;
							person[i].pathtarget = finaltarget;
						}
						}
					}

					// Assassin
					if((person[i].killtarget>-1&&person[i].type!=civiliantype)&&!person[i].running){
						// Dead target?
						if(person[person[i].killtarget].health<=0&&person[i].type==eviltype){
							person[i].playerrotation2 = 0;
							person[i].whichgun = nogun;
							person[i].targetanimation = walkanim;
							person[i].lastdistancevictim = 200000;
							person[i].pathnum = -1;
							enemystate = 1;
							person[i].killtarget = -1;
							realcheck = 1;
						}

						if(person[i].type==zombietype&&person[person[i].killtarget].health<=0){
							if(person[person[i].killtarget].eaten!=i){
								person[i].playerrotation2 = 0;
								person[i].targetanimation = zombiewalkanim;
								person[i].lastdistancevictim = 200000;
								person[i].pathnum = -1;
								realcheck = 1;
								person[i].killtarget = -1;
							}

							if(person[person[i].killtarget].eaten == i && person[i].targetanimation != zombieeatanim) {
								person[i].targetanimation = zombieeatanim;
								person[i].targetframe = 0;
								person[i].target = 0;
							}
							enemystate = 1;
						}

						if(person[person[i].killtarget].health>0){
						if(person[person[i].killtarget].skeleton.free){
							person[person[i].killtarget].playercoords=person[person[i].killtarget].averageloc;
						}

						// If pathfind
						if(realcheck){
						leastdistance=2000000;
						person[i].lastdistancevictim=2000000;
						closesttarget=-1;

						//Check best path
						for(int j=0;j<path.vertexNum;j++){
							person[i].pathtarget.x=path.vertex[j].x;
							person[i].pathtarget.z=path.vertex[j].z;
							person[i].pathtarget.y=path.vertex[j].y;
							person[i].pathtarget*=person[i].pathsize;
							person[i].pathtarget.x+=person[i].whichblockx*block_spacing;
							person[i].pathtarget.z+=person[i].whichblocky*block_spacing;

							if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<person[i].lastdistancevictim&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){
								leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
								person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
								closesttarget=j;
								finaltarget=person[i].pathtarget;
							}
						}

						leastdistance=2000000;
						for(int j=0;j<path.vertexNum;j++){
							person[i].pathtarget.x=path.vertex[j].x;
							person[i].pathtarget.z=path.vertex[j].z;
							person[i].pathtarget.y=path.vertex[j].y;
							person[i].pathtarget*=person[i].pathsize;
							person[i].pathtarget.x+=person[i].whichblockx*block_spacing;
							person[i].pathtarget.z+=person[i].whichblocky*block_spacing;

							if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<person[i].lastdistancevictim&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){
								leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
								person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
								closesttarget=j;
								finaltarget=person[i].pathtarget;
							}
						}

						//Check other blocks?
						if((closesttarget==person[i].pathnum)||closesttarget==-1){
							beginx=person[i].whichblockx-2;
							if(beginx<0)beginx=0;
							beginz=person[i].whichblocky-2;
							if(beginz<0)beginz=0;
							endx=person[i].whichblockx+2;
							if(endx>num_blocks-1)endx=num_blocks-1;
							endz=person[i].whichblocky+2;
							if(endz>num_blocks-1)endz=num_blocks-1;
							leastdistance=2000000;

							for(int l=beginx;l<=endx;l++){
								for(int m=beginx;m<=endx;m++){
									if(l!=person[i].whichblockx||m!=person[i].whichblocky){

									for(int j=0;j<path.vertexNum;j++){
										person[i].pathtarget.x=path.vertex[j].x;
										person[i].pathtarget.y=path.vertex[j].y;
										person[i].pathtarget.z=path.vertex[j].z;
										person[i].pathtarget*=person[i].pathsize;
										person[i].pathtarget.x+=l*block_spacing;
										person[i].pathtarget.z+=m*block_spacing;

										if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<findDistancefast(person[i].playercoords,person[person[i].killtarget].playercoords)&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[l][m])==-1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){
											leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
											closesttarget=j;
											finaltarget=person[i].pathtarget;
											person[i].whichblockx=l;
											person[i].whichblocky=m;
										}
									}
									}
								}
							 }
						}

						if(closesttarget!=-1){
							person[i].onpath=1;
							person[i].pathnum=closesttarget;
							person[i].pathtarget=finaltarget;
						}
						}

						//Check killtargetvisible
						person[i].killtargetvisible=1;

						if(person[person[i].killtarget].health<=0)person[i].killtargetvisible=0;

						if(closesttarget!=-1&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>30000)person[i].killtargetvisible=0;

						if(person[i].killtarget==0&&visions==1)person[i].killtargetvisible=0;

						if(person[i].killtargetvisible){
							beginx=person[i].whichblockx-2;
							if(beginx<0)beginx=0;
							beginz=person[i].whichblocky-2;
							if(beginz<0)beginz=0;
							endx=person[i].whichblockx+2;
							if(endx>num_blocks-1)endx=num_blocks-1;
							endz=person[i].whichblocky+2;
							if(endz>num_blocks-1)endz=num_blocks-1;

							for(int l=beginx;l<=endx;l++){
								for(int m=beginx;m<=endx;m++){
									move.x=l*block_spacing;
									move.z=m*block_spacing;
									move.y=-3;
									if(person[i].killtargetvisible){
										if(blocksimple.LineCheck2(person[i].playercoords,person[person[i].killtarget].playercoords,&blah,move,cityrotation[l][m])!=-1)
										{
											person[i].killtargetvisible=0;
										}
									}
								}
							 }
							}

							if(person[i].type==eviltype){
								 if(!person[i].killtargetvisible&&person[i].targetanimation==idleanim){
									person[i].targetanimation=joganim;
								 }

								 if(!person[i].killtargetvisible){
									person[i].aiming=0;
								 }

								 if(person[i].killtargetvisible){
									person[i].onpath=0;
									person[i].lastdistancevictim=200000;
									person[i].pathnum=-1;

									if(person[i].whichgun==nogun){
										person[i].whichgun=possiblegun[randUint(numpossibleguns)];
										person[i].reloads[person[i].whichgun]=1;
										if(person[i].whichgun==knife)person[i].speedmult=.8+.5*difficulty;
									}

									if(person[i].aiming==0)person[i].shotdelay=shotdelayamount/difficulty;

									person[i].aiming=1;

									if(person[i].reloading>0)person[i].aiming=0;

									if(person[i].whichgun==handgun1||person[i].whichgun==handgun2)person[i].playerrotation2=-10;

									if(person[i].whichgun==assaultrifle||person[i].whichgun==sniperrifle||person[i].whichgun==shotgun)person[i].playerrotation2=20;

									tooclose=1300;
									toofar=3000;

									if(person[i].whichgun==shotgun){
										tooclose=1400;
										toofar=5000;
									}

									if(person[i].whichgun==assaultrifle){
										tooclose=5000;
										toofar=9000;
									}

									if(person[i].whichgun==sniperrifle){
										tooclose=10000;
										toofar=20000;
									}

									if(person[i].whichgun==knife){
										tooclose=20;
										toofar=20000;
									}

									if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>toofar)
										person[i].targetanimation=joganim;

									if((findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=tooclose&&person[person[i].killtarget].skeleton.free==0)||(tooclose>200&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=200)||(tooclose<=200&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<tooclose)){
										if(person[i].targetanimation!=idleanim){
											person[i].targetanimation=idleanim;
											person[i].targetframe=0;
											person[i].target=0;
										}

										if(person[i].whichgun==knife&&person[person[i].killtarget].health==100){
											murderer=i;
											person[i].attacktarget=0;
											person[i].attackframe=0;

											if(person[person[i].killtarget].type!=zombietype)
											{
												auto stabpos = person[i].playercoords + flatfacing - camera.position;
												playSound(gSourceID[knifeslashsound],
													stabpos.x, stabpos.y, stabpos.z);
												person[person[i].killtarget].bjoint1=&person[person[i].killtarget].skeleton.joints[neck];
												person[person[i].killtarget].bjoint2=&person[person[i].killtarget].skeleton.joints[neck];
												person[person[i].killtarget].bleeding=1;
												person[person[i].killtarget].bleeddelay=1;
												person[person[i].killtarget].health-=20;
												person[person[i].killtarget].targetanimation=chestpainanim;
												person[person[i].killtarget].targetframe=0;
												person[person[i].killtarget].target=0;
												person[person[i].killtarget].longdead=1;
											}
										}
									}
									finaltarget=person[person[i].killtarget].playercoords;
								 }
							}

							if(person[i].type==zombietype&&person[person[i].killtarget].health>0){
								 if(!person[i].killtargetvisible&&person[i].targetanimation==idleanim){
									person[i].targetanimation=zombiejoganim;
								 }

								 if(!person[i].killtargetvisible){
									person[i].aiming=0;
								 }

								 if(person[i].killtargetvisible){
									person[i].onpath=0;
									person[i].lastdistancevictim=200000;
									person[i].pathnum=-1;

									if(person[i].aiming==0)person[i].shotdelay=shotdelayamount/difficulty;

									if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>20||person[i].targetanimation!=idleanim)
										person[i].targetanimation=zombiejoganim;

									if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=20){
										murderer=i;
										person[person[i].killtarget].health=0;
										person[person[i].killtarget].eaten=i;
									}
									finaltarget=person[person[i].killtarget].playercoords;
								 }
							}

						 if(person[i].killtargetvisible||realcheck)person[i].pathtarget=finaltarget;
						 if(realcheck)person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
						}
					}

					if(person[i].targetanimation!=zombieeatanim||person[i].type!=zombietype){
						towards=person[i].playercoords-person[i].pathtarget;
						Normalise(&towards);
						person[i].playerrotation=asin(0-towards.x)*360/6.28;
						if(towards.z>0)person[i].playerrotation=180-person[i].playerrotation;
					}
				}
			}

			person[i].whichblockx=((person[i].playercoords.x+block_spacing/2)/block_spacing);
			person[i].whichblocky=((person[i].playercoords.z+block_spacing/2)/block_spacing);
			if(!person[i].onground)person[i].velocity.y+=multiplier*gravity;
			if(!person[i].onground&&(i!=0||visions!=1))person[i].playercoords+=person[i].velocity*multiplier;

			//Death by bleeding/shock
			if(person[i].health<=0){
				person[i].skeleton.offset=0;
				person[i].skeleton.free=1;
				person[i].longdead=1;

				for (auto& joint : person[i].skeleton.joints) {
					joint.position += joint.offset;
					joint.position = DoRotation(joint.position, 0, person[i].playerrotation, 0);
					joint.position += person[i].playercoords;
					joint.realoldposition = joint.position;
					joint.velocity = DoRotation(joint.velocity, 0, person[i].playerrotation, 0);
					joint.velocity += person[i].velocity;
					joint.velocity += person[i].facing * 4;
				}
			}
		 }

		//Rag doll
		if(person[i].skeleton.free==1&&person[i].longdead>0){
			person[i].whichblockx=((person[i].skeleton.joints[0].position.x+block_spacing/2)/block_spacing);
			person[i].whichblocky=((person[i].skeleton.joints[0].position.z+block_spacing/2)/block_spacing);

			move = {
				(float) person[i].whichblockx * block_spacing,
				0.0f,
				(float) person[i].whichblocky * block_spacing,
			};
			person[i].skeleton.DoGravity();

			if(person[i].averageloc.y<=50)person[i].skeleton.DoConstraints(&blocksimplecollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
			if(person[i].averageloc.y>50)person[i].skeleton.DoConstraints(&blockcollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);

			person[i].oldaverageloc=person[i].averageloc;
			person[i].averageloc = {};

			for (auto& joint : person[i].skeleton.joints)
				person[i].averageloc += joint.position;

			person[i].averageloc /= max_joints;
			person[i].playercoords=person[i].averageloc;
			if(person[i].longdead<multiplier/2&&person[i].longdead>0)person[i].DrawSkeleton(i);
			if(findDistancefast(person[i].averageloc,person[i].oldaverageloc)<.2*multiplier)person[i].longdead-=multiplier/2;
		}

		if(person[i].skeleton.free==1&&person[i].longdead<=0&&person[i].health>0&&person[i].longdead!=-1){
			person[i].longdead=1;
			person[i].skeleton.free=0;
			person[i].currentanimation=lyinganim;
			person[i].target=0;
			person[i].targetframe=0;

			//Get up from front or back?
			if(person[i].skeleton.forward.y>0)
			person[i].targetanimation=getupfrontanim;
			else
			person[i].targetanimation=getupbackanim;

			//Find playercoords
			person[i].playercoords=person[i].averageloc;
			for (auto& joint : person[i].skeleton.joints)
				if (joint.position.y > person[i].playercoords.y)
					person[i].playercoords.y = joint.position.y;

			//Find orientation
			XYZ firsttop=person[i].skeleton.joints[neck].position-person[i].skeleton.joints[groin].position;
			Normalise(&firsttop);
			person[i].playerrotation=acos(0-firsttop.z);
			person[i].playerrotation*=360/6.28;
			if(0>firsttop.x)person[i].playerrotation=360-person[i].playerrotation;
			person[i].playerrotation*=-1;
			person[i].playervelocity = {};
			if(person[i].targetanimation==getupfrontanim)person[i].playerrotation+=180;

			for (int j = 0; j < max_joints; ++j) {
				person[i].tempanimation.position[j][0]=person[i].skeleton.joints[j].position-person[i].playercoords;
				person[i].tempanimation.position[j][0]=DoRotation(person[i].tempanimation.position[j][0],0,-person[i].playerrotation,0);
			}
		}
	}

	XYZ velocity;

	if(person[0].attackframe>1||(person[0].attackframe>=0&&person[0].currentanimation==joganim)){

		if(person[person[0].killtarget].skeleton.free<1&&person[0].killtarget!=0&&(person[0].aiming<1||person[0].whichgun==nogun||person[0].whichgun==knife||person[0].targetanimation==joganim)){
			auto soundpos = person[0].playercoords + flatfacing
				- camera.position;
			if (person[person[0].killtarget].type != zombietype) {
				if (person[0].whichgun != knife) {
					playSound(gSourceID[headwhacksound],
						soundpos.x, soundpos.y, soundpos.z);
				} else {
					playSound(gSourceID[knifeslashsound],
						soundpos.x, soundpos.y, soundpos.z);

					person[person[0].killtarget].bjoint1=&person[person[0].killtarget].skeleton.joints[neck];
					person[person[0].killtarget].bjoint2=&person[person[0].killtarget].skeleton.joints[neck];
					person[person[0].killtarget].bleeding=1;
					person[person[0].killtarget].bleeddelay=1;
					person[0].bjoint1=&person[0].skeleton.joints[righthand];
					person[0].bjoint2=&person[0].skeleton.joints[righthand];

					person[0].bleeding=1;
					person[0].bleeddelay=1;

					velocity=DoRotation(flatfacing,0,70,0)*50+person[0].velocity*2;
					velocity.y+=30;
					sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[neck].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.3, 2);
					sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[neck].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.2, 3);
					sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[neck].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.1, 4);
				}

				person[person[0].killtarget].health-=100;
				person[person[0].killtarget].skeleton.free=1;
				person[person[0].killtarget].longdead=1;

				for (auto& joint : person[person[0].killtarget].skeleton.joints) {
					joint.position = DoRotation(joint.position,
						0, person[person[0].killtarget].playerrotation, 0);
					joint.position += person[person[0].killtarget].playercoords;
					joint.realoldposition = joint.position;
					joint.velocity = person[person[0].killtarget].velocity;
					joint.velocity.x += randInt(-4, 4);
					joint.velocity.y += randInt(-4, 4);
					joint.velocity.z += randInt(-4, 4);
				}

				if(person[0].whichgun!=knife){
					person[person[0].killtarget].skeleton.joints[head].velocity+=DoRotation(flatfacing,0,40,0)*50;
					person[person[0].killtarget].skeleton.joints[head].velocity+=person[0].velocity*2;
				}
			} else if (!whacked) {
				whacked = true;
				if (person[0].whichgun != knife) {
					playSound(gSourceID[headwhacksound],
						soundpos.x, soundpos.y, soundpos.z);
				} else {
					playSound(gSourceID[knifeslashsound],
						soundpos.x, soundpos.y, soundpos.z);

					person[person[0].killtarget].bjoint1=&person[person[0].killtarget].skeleton.joints[neck];
					person[person[0].killtarget].bjoint2=&person[person[0].killtarget].skeleton.joints[neck];

					person[person[0].killtarget].bleeddelay=1;

					person[0].bjoint1=&person[0].skeleton.joints[righthand];
					person[0].bjoint2=&person[0].skeleton.joints[righthand];

					person[0].bleeding=1;
					person[0].bleeddelay=1;

					velocity=DoRotation(flatfacing,0,70,0)*50+person[0].velocity*2;
					velocity.y+=30;

					sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[neck].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.3, 2);
					sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[neck].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.2, 3);
					sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[neck].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.1, 4);
				}

				person[person[0].killtarget].health-=200;
				person[person[0].killtarget].maxhealth-=20;
				person[person[0].killtarget].skeleton.free=1;
				person[person[0].killtarget].longdead=1;

				for (auto& joint : person[person[0].killtarget].skeleton.joints) {
					joint.position = DoRotation(joint.position, 0, person[person[0].killtarget].playerrotation, 0);
					joint.position += person[person[0].killtarget].playercoords;
					joint.realoldposition = joint.position;
					joint.velocity = person[person[0].killtarget].velocity;

					joint.velocity.x += randInt(-4, 4);
					joint.velocity.y += randInt(-4, 4);
					joint.velocity.z += randInt(-4, 4);
				}

				if(person[0].whichgun!=knife){
					person[person[0].killtarget].skeleton.joints[head].velocity+=DoRotation(flatfacing,0,40,0)*50;
					person[person[0].killtarget].skeleton.joints[head].velocity+=person[0].velocity*2;
				}
			}
		}
	}

	//Tackle
	if (person[0].currentanimation == diveanim && visions == 0) {
		for (int i = 1; i < numpeople; i++) {
			if (person[i].skeleton.free > 0
			    || findDistancefast(person[i].playercoords,
			                        person[0].playercoords
			                        + flatfacing) > 22)
				continue;

			float gLoc[] {
				flatfacing.x / soundscalefactor / 2,
				flatfacing.y / soundscalefactor / 2,
				flatfacing.z / soundscalefactor / 2,
			};

			alSourcefv(gSourceID[headwhacksound],
			           AL_POSITION, gLoc);
			alSourcePlay(gSourceID[headwhacksound]);
			person[i].skeleton.free = 1;
			person[i].longdead = 1;

			for (auto& joint : person[i].skeleton.joints) {
				joint.position = DoRotation(joint.position, 0, person[i].playerrotation, 0);
				joint.position += person[i].playercoords;
				joint.realoldposition = joint.position;
				joint.velocity = person[0].velocity;
				joint.velocity.y = -10;
				joint.velocity.x += randInt(-4, 4);
				joint.velocity.y += randInt(-4, 4);
				joint.velocity.z += randInt(-4, 4);
			}
		}
	}

	// Empty magazine
	if (person[0].firing && person[0].ammo <= 0) {
		auto soundpos = person[0].playercoords - camera.position;
		playSound(gSourceID[clicksound],
			soundpos.x, soundpos.y, soundpos.z);
		person[0].firing = false;
	}

	XYZ wallhit;
	XYZ start;
	XYZ finalwallhit;
	int numshots;
	XYZ hitnorm;
	XYZ hitmove;
	int hitpoly = 0;
	float hitrotation = 0.0f;
	Model* model = NULL;

	for (int j = 0; j < numpeople; j++) {
		if (j && person[j].type != eviltype)
			continue;

		if (person[j].ammo <= 0
		    || person[j].reloading > 0
		    || person[j].targetanimation == joganim
		    || person[j].aimamount < 1)
			person[j].firing = false;
		else if (j)
			person[j].firing = person[j].whichgun != nogun
				&& person[j].whichgun != knife
				&& person[j].killtargetvisible
				&& person[j].shotdelay < 0;

		if (j && person[j].killtargetvisible
		    && person[j].whichgun != nogun
		    && person[j].whichgun != knife) {
			person[j].aiming = 1;
			if (person[j].shotdelay > 0)
				person[j].shotdelay -= multiplier * 0.9;
		}

		if (person[j].skeleton.free == 1
		    || person[j].targetanimation == getupfrontanim
		    || person[j].targetanimation == getupbackanim)
			person[j].shotdelay = shotdelayamount
				/ difficulty;

		if (person[j].ammo == 0
		    && person[j].reloads[person[j].whichgun] > 0) {
			person[j].ammo = -1;
			person[j].aiming = 0;
		}

		if (!person[j].firing || person[j].aiming < 1 || person[j].recoil > 0)
			continue;
		if (j != 0 || person[j].whichgun != assaultrifle)
			person[j].firing = false;
		person[j].shotdelay = shotdelayamount / difficulty;

		HitStruct hitstruct, temphitstruct;
		person[j].litup = 1;
		person[j].recoil = 1;

		float olddistance = 0.0f, distance = 0.0f;
		float totalarea = 0.0f;
		int whichhit = -1;

		numshots = (person[j].whichgun == shotgun) ? 7 : 1;
		if (person[j].whichgun != grenade)
			person[j].ammo--;

		for (int p = 0; p < numshots; p++) {
			XYZ aim;
			if (j)
				aim = aimBot(this, j);
			else if (!zoom)
				aim = aimPlayer(this);
			else
				aim = facing;
			Normalise(&aim);

			int aimjoint;
			switch (person[j].whichgun) {
			case handgun1:
			case handgun2:
				aimjoint = rightwrist;
				break;
			default:
				aimjoint = lefthand;
			}
			start = person[j].playercoords
				+ DoRotation(person[j].skeleton.joints[aimjoint].position,
					0, person[j].playerrotation, 0);

			if (j == 0 && person[j].grenphase) {
				person[j].grenphase = false;
				sprites.MakeSprite(grenadesprite, 1, 1, 1, 1,
					start, aim * 200, 1.01);
			}

			auto startsub = DoRotation(aim,
				0, -person[j].playerrotation, 0);
			startsub = DoRotation(startsub, 90, 0, 0);
			startsub *= DoRotation(startsub,
				0, person[j].playerrotation,0);
			switch (person[j].whichgun) {
			case sniperrifle:
			case shotgun:
				start -= startsub * 0.35f;
				break;
			case handgun1:
			case handgun2:
				start -= startsub * 0.55f;
				break;
			default: // assaultrifle
				start -= startsub * 0.25f;
			}

			if (p == numshots - 1) {
				auto crouch = person[j].currentanimation == crouchanim;
				float rot = 0.0f, rot2 = 0.0f;
				switch (person[j].whichgun) {
				case sniperrifle:
				case shotgun:
					rot2 = crouch ? 3.0f : 7.0f;
					break;
				case handgun1:
					rot2 = crouch ? 4.0f : 6.0f;
					break;
				case handgun2:
					rot2 = crouch ? 3.0f : 5.0f;
					break;
				case assaultrifle:
					rot = randInt(-100, 100) / (crouch ? 60.0f : 50.0f);
					rot2 = crouch ? 1.5f : 2.3f;
					break;
				}
				camera.rotation -= rot;
				camera.rotation2 -= rot2;

				ALuint gunsound;
				switch (person[j].whichgun) {
				case sniperrifle:
					gunsound = gSourceID[riflesound];
					break;
				case shotgun:
					gunsound = gSourceID[shotgunsound];
					break;
				case handgun1:
					gunsound = gSourceID[pistol1sound];
					break;
				case handgun2:
					gunsound = gSourceID[pistol2sound];
					break;
				default: // assaultrifle
					gunsound = gSourceID[machinegunsound];
				}
				auto soundpos = start - camera.position;
				playSound(gunsound, soundpos.x,
					soundpos.y, soundpos.z);
			}

			XYZ end {start + aim * 1000};
			int bulletstrength=1;
			int firstpass=-1;

			for(int m=0;m<bulletstrength;m++){

				//People

				whichhit=-1;

				for(int i=0;i<numpeople;i++){

					if(i!=j&&i!=firstpass&&person[i].existing){

						temphitstruct=person[i].BulletCollideWithPlayer(i, start, end);

						if(temphitstruct.collision){

							distance=findDistancefast(start,temphitstruct.hitlocation);

							if(distance<olddistance||whichhit==-1){

								end=temphitstruct.hitlocation;

								olddistance=distance;

								hitstruct=temphitstruct;

								whichhit=i;

							}

						}

					}

				}

				// Blocks
				wallhit = {};
				beginx=(person[j].playercoords.x+block_spacing/2)/block_spacing-3;

				if(beginx<0)beginx=0;

				beginz=(person[j].playercoords.z+block_spacing/2)/block_spacing-3;

				if(beginz<0)beginz=0;

				endx=(person[j].playercoords.x+block_spacing/2)/block_spacing+3;

				if(endx>num_blocks-1)endx=num_blocks-1;

				endz=(person[j].playercoords.z+block_spacing/2)/block_spacing+3;

				if(endz>num_blocks-1)endz=num_blocks-1;

				if(beginx<endx&&beginz<endz)

				finalwallhit = {};
				for(int i=beginx;i<=endx;i++)
					for(int j=beginz;j<=endz;j++){
						move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
						whichtri=blocks[citytype[i][j]].LineCheck2(start,end,&wallhit,move,cityrotation[i][j]*90);

						if(whichtri!=-1){

							whichhit=-1;

							end=wallhit;

							finalwallhit=wallhit;

							hitnorm=DoRotation(blocks[citytype[i][j]].normals[whichtri],0,cityrotation[i][j]*90,0);

							hitmove=move;

							hitrotation=cityrotation[i][j]*90;

							hitpoly=whichtri;

							model=&blocks[citytype[i][j]];

							if(j==0&&blocks[citytype[i][j]].normals[whichtri].y>.9)bulletstrength=2;
						}
					}
				wallhit = {camera.position.x, 0.0f, camera.position.z};

				whichtri=Bigstreet.LineCheck2(start,end,&wallhit,wallhit,0);

				if(whichtri!=-1){
					end.y-=.5;
					end=wallhit;
					finalwallhit=wallhit;
					bulletstrength=2;
					hitnorm = {0.0f, 1.0f, 0.0f};
					hitmove = {};
					hitrotation=0;
				}

				if(m==0){

					if(j==0&&slomo==2){
						alSourceStop(gSourceID[whichsong]);

						alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);

						alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);

						if(person[0].whichgun==knife)whichsong=knifesong;

						if(person[0].whichgun!=knife)whichsong=shootsong;

						if(type==zombie_type)whichsong=zombiesong;

						alSourcef(gSourceID[whichsong], AL_PITCH, 1);

						alSourcePlay(gSourceID[whichsong]);

						alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);

						alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);

						slomo=0;

						if(whichhit==-1)alSourcePlay(gSourceID[disguisekillsound]);

						flashamount=.5;

						flashr=1;flashg=1;flashb=1;

					}

				}

				//Impact

				XYZ oldend {end};

				//with person

				if(whichhit!=-1&&whichhit!=firstpass){

					if(j==0)person[whichhit].dead=1;

					if(whichhit==1){

						murderer=j;

					}

					if(person[whichhit].health==100&&j==0){

						if(person[whichhit].type==civiliantype)civkills++;

						if(person[whichhit].type==eviltype)goodkills++;

					}

					if(person[whichhit].health==100&&j!=0){

						badkills++;

					}

					bool penetrate = (numshots > 1) ? 0 : !randUint(3);
					if (penetrate) {
						bulletstrength = 2;
						firstpass = whichhit;
						end = start + aim * 1000;
					}

					if(person[j].whichgun==assaultrifle)person[whichhit].health-=20;

					if(person[j].whichgun==assaultrifle&&person[whichhit].type==zombietype)person[whichhit].health-=60;

					if(person[j].whichgun==handgun1){

						if(person[whichhit].type!=zombietype)person[whichhit].health-=100;

						if(person[whichhit].type==zombietype)person[whichhit].health-=100;

						person[whichhit].DoAnimations(whichhit);

					}

					if(person[j].whichgun==handgun2)person[whichhit].health-=20;

					if(person[j].whichgun==handgun2&&person[whichhit].type==zombietype)person[whichhit].health-=60;

					if(person[j].whichgun==sniperrifle&&m!=0)person[whichhit].health-=30;

					if(person[j].whichgun==shotgun)person[whichhit].health-=60;

					if(person[j].whichgun==sniperrifle&&m==0){

						if(person[whichhit].type!=zombietype)person[whichhit].health-=100;

						if(person[whichhit].type==zombietype)person[whichhit].health-=120;

						person[whichhit].DoAnimations(whichhit);

					}

					if(hitstruct.joint1->modelnum==headmodel&&person[whichhit].type!=zombietype){

						person[whichhit].health-=60;

					}

					if(person[whichhit].type==zombietype)person[whichhit].speedmult-=.05;

					if(person[whichhit].type==zombietype)person[whichhit].maxhealth-=10;

					if (whichhit == 0) {
						bulletstrength = 1;
						person[0].health = 100;
						flashamount = 1;
						flashr = flashg = flashb = 0;
						auto soundsrc = (hitstruct.hitlocation - camera.position) / soundscalefactor;
						float gLoc[] {soundsrc.x, soundsrc.y, soundsrc.z};
						alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc);
						alSourcePlay(gSourceID[bodywhacksound]);
					}

					person[whichhit].longdead=1;

					if(person[whichhit].health<=0){

						person[whichhit].skeleton.offset=0;

						if(person[whichhit].skeleton.free!=1){

							person[whichhit].skeleton.free=1;

							totalarea=0;

							for (auto& joint : person[whichhit].skeleton.joints) {
								joint.position = DoRotation(joint.position, 0, person[whichhit].playerrotation, 0);
								joint.position += person[whichhit].playercoords;
								joint.realoldposition = joint.position;
								joint.velocity = person[whichhit].velocity;
								joint.velocity.x += randInt(-4, 4);
								joint.velocity.y += randInt(-4, 4);
								joint.velocity.z += randInt(-4, 4);
							}
						}

						for (auto& joint : person[whichhit].skeleton.joints) {
							auto distance = findDistancefast(joint.position, hitstruct.hitlocation);
							if (distance < 200) {
								totalarea += 200 / distance;
								joint.velocity += aim * 200 / distance / totalarea * 200;
							}
						}
					}

					if(person[whichhit].health>0){

						if (person[whichhit].killtargetvisible == 0
						    && person[whichhit].type != zombietype
						    && person[whichhit].currentanimation !=getupfrontanim
						    && person[whichhit].currentanimation != getupbackanim) {
							if(hitstruct.joint1->modelnum==headmodel)person[whichhit].targetanimation=headpainanim;

							if(hitstruct.joint1->modelnum==chestmodel)person[whichhit].targetanimation=chestpainanim;

							if(hitstruct.joint1->modelnum==abdomenmodel)person[whichhit].targetanimation=stomachpainanim;

							if(hitstruct.joint1->label==rightelbow||hitstruct.joint1->label==rightshoulder||hitstruct.joint1->label==rightwrist||hitstruct.joint1->label==righthand)person[whichhit].targetanimation=rightarmpainanim;

							if(hitstruct.joint1->label==leftelbow||hitstruct.joint1->label==leftshoulder||hitstruct.joint1->label==leftwrist||hitstruct.joint1->label==lefthand)person[whichhit].targetanimation=leftarmpainanim;

							if(hitstruct.joint1->label==rightknee||hitstruct.joint1->label==righthip||hitstruct.joint1->label==rightankle||hitstruct.joint1->label==rightfoot)person[whichhit].targetanimation=rightlegpainanim;

							if(hitstruct.joint1->label==leftknee||hitstruct.joint1->label==lefthip||hitstruct.joint1->label==leftankle||hitstruct.joint1->label==leftfoot)person[whichhit].targetanimation=leftlegpainanim;

							person[whichhit].targetframe=0;

							person[whichhit].target=0;

						}

						person[whichhit].skeleton.offset=1;

						for (auto& joint : person[whichhit].skeleton.joints) {
							auto distance = findDistancefast(DoRotation(joint.position, 0, person[whichhit].playerrotation, 0) + person[whichhit].playercoords, hitstruct.hitlocation);
							if(distance < 200) {
								totalarea += 200 / distance;
								joint.offset += DoRotation(aim * 200 / distance / totalarea * 10,
									0, -person[whichhit].playerrotation, 0);
							}
							if (findLengthfast(joint.offset) > 36) {
								Normalise(&joint.offset);
								joint.offset *= 6;
							}
						}
					}

					if(hitstruct.joint1->modelnum==headmodel&&person[whichhit].health<=0){

						for (int j = 0; j < max_joints; ++j) {

							if(&person[whichhit].skeleton.joints[j]==hitstruct.joint1||&person[whichhit].skeleton.joints[j]==hitstruct.joint2){
								if (j != abdomen && j != groin && j != neck) {
									sprites.MakeSprite(bloodspritedown, 0.8f, 1, 0.2f, 0.2f,
										person[whichhit].skeleton.joints[j].position,
										person[whichhit].skeleton.joints[j].velocity / 3, 9);
									for (int tmp = 0; tmp < 4; ++tmp)
										sprites.MakeSprite(bloodspritedown, 0.8f, 1, 0.2f, 0.2f,
											person[whichhit].skeleton.joints[j].position,
											DoRotation(person[whichhit].skeleton.joints[j].velocity / 3,
												randUint(360), randUint(360), 0) / 5, 5);
									person[whichhit].skeleton.DeleteJoint(j);
									person[whichhit].skeleton.broken=1;
									person[whichhit].health=-10000;
									person[whichhit].skeleton.joints[j].existing=0;
									if(person[whichhit].type==zombietype)score+=300;
								}
							}
						}
					}

					XYZ velocity;

					velocity=aim*-8;

					//blood

					if (hitstruct.joint1->modelnum != headmodel) {

					if(person[j].whichgun==sniperrifle)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 5);

					if(person[j].whichgun==sniperrifle&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 7);

					if(person[j].whichgun==shotgun)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 5);

					if(person[j].whichgun==shotgun&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 7);

					if(person[j].whichgun==assaultrifle)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 3);

					if(person[j].whichgun==assaultrifle&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 7);

					if(person[j].whichgun==handgun1)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 3);

					if(person[j].whichgun==handgun1&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 4);

					if(person[j].whichgun==handgun2)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 3);

					if(person[j].whichgun==handgun2&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 4);

					}else{

						sprites.MakeSprite(bloodspritenoup, 1, 1, .2, .2, hitstruct.hitlocation, velocity*0, 6);

						sprites.MakeSprite(bloodspritenoup, 1, 1, .5, .5, hitstruct.hitlocation, velocity*-2, 7);

						sprites.MakeSprite(bloodspritenoup, 1, 1, .2, .2, hitstruct.hitlocation, velocity*-3, 10);

					}

					person[whichhit].bjoint1=hitstruct.joint1;
					person[whichhit].bjoint2=hitstruct.joint2;
					person[whichhit].bleeding=1;
					person[whichhit].bleeddelay=1;

					auto hitsound = (hitstruct.joint1->modelnum == headmodel)
						? gSourceID[headshotsound]
						: gSourceID[bodyhitsound];
					auto hitpos = hitstruct.hitlocation
						- camera.position;
					playSound(hitsound, hitpos.x, hitpos.y, hitpos.z);
				}

				// with wall
				if(oldend==finalwallhit){

					decals.MakeDecal(bullethole, finalwallhit,.7,hitnorm, hitpoly, model, hitmove, hitrotation);

					XYZ velocity;

					velocity=aim*-4;

					velocity=hitnorm*3;

					if(person[j].whichgun==sniperrifle){

						sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 10);

						sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 2);

					}

					if(person[j].whichgun==shotgun){

						sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 5);

						sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, .8);

					}

					if(person[j].whichgun==assaultrifle){

						sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6);

						sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1);

					}

					if(person[j].whichgun==handgun1){

						sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6);

						sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1);

					}

					if(person[j].whichgun==handgun2){

						sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6);

						sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1);

					}

					auto soundpos = finalwallhit - camera.position;
					playSound(gSourceID[wallhitsound],
						soundpos.x, soundpos.y, soundpos.z);
				}

				lastshot[0]=start;

				lastshot[1]=oldend;

				velocity=aim*8;

				if(person[j].whichgun!=sniperrifle&&person[j].whichgun!=shotgun&&p==numshots-1)sprites.MakeSprite(smokesprite, .3, 1, 1, 1, start+aim*1.5, velocity, 3);

				if(person[j].whichgun==shotgun&&p==numshots-1)sprites.MakeSprite(smokesprite, .4, 1, 1, 1, start+aim*1.5, velocity, 5);

				if(person[j].whichgun==sniperrifle&&!zoom)sprites.MakeSprite(smokesprite, .3, 1, 1, 1, start+aim*2.2, velocity, 4);

				if(j!=0||zoom==0)sprites.MakeSprite(bullet, .07, 1, 1, .7, lastshot[0]+aim*1, lastshot[1], .2);

				// Nearby bullet whoosh
				XYZ* a = &lastshot[0];
				*a += aim;
				XYZ* b = &lastshot[1];
				XYZ* c = &camera.position;
				XYZ nearest {};
				long dot_ta = (c->x - a->x) * (b->x - a->x)
					+ (c->y - a->y) * (b->y - a->y)
					+ (c->z - a->z) * (b->z - a->z);
				long dot_tb = (c->x - b->x) * (a->x - b->x)
					+ (c->y - b->y) * (a->y - b->y)
					+ (c->z - b->z) * (a->z - b->z);

				if (dot_ta > 0 && dot_tb > 0) {
					nearest.x = a->x + ((b->x - a->x) * dot_ta) / (dot_ta + dot_tb);
					nearest.y = a->y + ((b->y - a->y) * dot_ta) / (dot_ta + dot_tb);
					nearest.z = a->z + ((b->z - a->z) * dot_ta) / (dot_ta + dot_tb);
				}

				if (nearest.x
				    && findDistancefast(nearest, camera.position) < 10
				    && (thirdperson == 2 || j != 0)) {
					auto nearsound = nearest - camera.position;
					playSound(gSourceID[nearbulletsound],
						nearsound.x, nearsound.y, nearsound.z);
				}
			}
		}
	}

	if(lasersight&&person[0].whichgun!=grenade){

	for(int j=0;j<numpeople;j++){

		if(person[j].type==playertype){

			if(person[j].aiming>=1){

				//Firing
				XYZ end, aim;

				HitStruct hitstruct,temphitstruct;

				float olddistance = 0.0f;

				float distance;

				int whichhit=-1;

				if(!zoom||j!=0){

					if(person[j].whichgun==assaultrifle)aim=DoRotation(person[j].skeleton.joints[lefthand].position-person[j].skeleton.joints[righthand].position,0,person[j].playerrotation-2.5,0);

					if(person[j].whichgun==sniperrifle)aim=DoRotation(person[j].skeleton.joints[lefthand].position-person[j].skeleton.joints[righthand].position,0,person[j].playerrotation+4,0);

					if(person[j].whichgun==shotgun)aim=DoRotation(person[j].skeleton.joints[lefthand].position-person[j].skeleton.joints[righthand].position,0,person[j].playerrotation+4,0);

					if(person[j].whichgun==handgun1&&!thirdperson&&j==0)aim=DoRotation(person[j].skeleton.joints[righthand].position-(person[j].skeleton.joints[head].position*.65+person[j].skeleton.joints[neck].position*.35),0,person[j].playerrotation-.9,0);

					if(person[j].whichgun==handgun1&&(thirdperson||j!=0))aim=DoRotation(person[j].skeleton.joints[righthand].position-(person[j].skeleton.joints[head].position*.35+person[j].skeleton.joints[neck].position*.65),0,person[j].playerrotation-.9,0);

					if(person[j].whichgun==handgun2&&!thirdperson&&j==0)aim=DoRotation(person[j].skeleton.joints[righthand].position-(person[j].skeleton.joints[head].position*.65+person[j].skeleton.joints[neck].position*.35),0,person[j].playerrotation-.9,0);

					if(person[j].whichgun==handgun2&&(thirdperson||j!=0))aim=DoRotation(person[j].skeleton.joints[righthand].position-(person[j].skeleton.joints[head].position*.35+person[j].skeleton.joints[neck].position*.65),0,person[j].playerrotation-.9,0);

				}

				if(zoom&&j==0){

					start=camera.position;

					aim=facing;

				}

				Normalise(&aim);

				if(person[j].whichgun==sniperrifle){

					start=person[j].playercoords+DoRotation(person[j].skeleton.joints[lefthand].position,0,person[j].playerrotation,0);

					start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(0-.4);

				}

				if(person[j].whichgun==shotgun){

					start=person[j].playercoords+DoRotation(person[j].skeleton.joints[lefthand].position,0,person[j].playerrotation,0);

					start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(0-.4);

				}

				if(person[j].whichgun==handgun1){

					start=person[j].playercoords+DoRotation(person[j].skeleton.joints[rightwrist].position,0,person[j].playerrotation,0);

					start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(.55-.4);

				}

				if(person[j].whichgun==handgun2){

					start=person[j].playercoords+DoRotation(person[j].skeleton.joints[rightwrist].position,0,person[j].playerrotation,0);

					start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(.55-.4);

				}

				if(person[j].whichgun==assaultrifle){

					start=person[j].playercoords+DoRotation(person[j].skeleton.joints[lefthand].position,0,person[j].playerrotation,0);

					start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(.25-.4);

				}

				end=start+aim*1000;

				// Blocks
				wallhit = {};
				beginx=(person[j].playercoords.x+block_spacing/2)/block_spacing-2;

				if(beginx<0)beginx=0;

				beginz=(person[j].playercoords.z+block_spacing/2)/block_spacing-2;

				if(beginz<0)beginz=0;

				endx=(person[j].playercoords.x+block_spacing/2)/block_spacing+2;

				if(endx>num_blocks-1)endx=num_blocks-1;

				endz=(person[j].playercoords.z+block_spacing/2)/block_spacing+2;

				if(endz>num_blocks-1)endz=num_blocks-1;

				if(beginx<endx&&beginz<endz)

				finalwallhit = {};
				for(int i=beginx;i<=endx;i++)
					for(int j=beginz;j<=endz;j++){
						move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
						whichtri=blocks[citytype[i][j]].LineCheck2(start,end,&wallhit,move,cityrotation[i][j]*90);

						if(whichtri!=-1){

							end=wallhit;

							finalwallhit=wallhit;

						}

					}
				wallhit = {camera.position.x, 0.0f, camera.position.z};
				whichtri=Bigstreet.LineCheck2(start,end,&wallhit,wallhit,0);

				if(whichtri!=-1){

					end=wallhit;

					finalwallhit=wallhit;

				}

				//People

				whichhit=-1;

				for(int i=0;i<numpeople;i++){

					if(i!=j&&findDistancefast(person[j].playercoords,person[i].playercoords)<20000){

						temphitstruct=person[i].BulletCollideWithPlayer(i, start, end);

						if(temphitstruct.collision){

							distance=findDistancefast(start,temphitstruct.hitlocation);

							if(distance<olddistance||whichhit==-1){

								end=temphitstruct.hitlocation;

								olddistance=distance;

								hitstruct=temphitstruct;

								whichhit=i;

							}

						}

					}

				}

				aimer[0]=start;

				aimer[1]=end;

				sprites.MakeSprite(bulletinstant, .4, 1, 0, 0, aimer[0], aimer[1], .2);

			}

		}

	}

	}

	//Snow
	snowdelay-=multiplier;
	while(snowdelay<0&&environment==snowy_environment){
		snowdelay+=1/precipitationdensity*2;
		velocity = {0.0f, -5.0f, 0.0f};
		start=camera.position;
		start.y+=precipitationvert;
		start.x += randUint(precipitationhorz);
		start.z += randUint(precipitationhorz);
		sprites.MakeSprite(snowsprite, 1, 1, 1, 1, start, velocity, 1.01);
	}

	while(snowdelay<0&&environment==rainy_environment){
		snowdelay+=1/precipitationdensity/4;
		velocity = {0.0f, -100.0f, 0.0f};
		start=camera.position;
		start.y+=precipitationvert;
		start.x += randUint(precipitationhorz) * 0.5f;
		start.z += randUint(precipitationhorz) * 0.5f;
		sprites.MakeSprite(rainsprite, .5, 1, 1, 1, start, velocity, 2.00);
	}

	//Grenade collision
	int wherex, wherey, whichsound;
	bool impact;
	for(int i=0;i<sprites.howmanysprites;i++){
		if(sprites.type[i]==grenadesprite||sprites.type[i]==spoonsprite||sprites.type[i]==pinsprite){
			impact=0;
			if(sprites.type[i]!=grenadesprite){
				sprites.brightness[i]-=multiplier*.2;
			}

			if(findLengthfast(sprites.velocity[i])>0){
				wherex=(sprites.location[i].x+block_spacing/2)/block_spacing;
				wherey=(sprites.location[i].z+block_spacing/2)/block_spacing;
				move = {(float) wherex * block_spacing, 0.0f, (float) wherey * block_spacing};
				whichtri=blocks[citytype[wherex][wherey]].LineCheck2(sprites.oldlocation[i],sprites.location[i],&wallhit,move,cityrotation[wherex][wherey]*90);

				if (whichtri != -1) {
					impact = 1;
					auto normalrotated = DoRotation(blocks[citytype[wherex][wherey]].normals[whichtri], 0, cityrotation[wherex][wherey] * 90, 0);
					if (sprites.size[i] > 1)
						decals.MakeDecal(crater, wallhit, 9, normalrotated, whichtri, &blocks[citytype[wherex][wherey]], move, cityrotation[wherex][wherey] * 90);
					sprites.location[i] = wallhit + normalrotated * 0.02f;
					ReflectVector(&sprites.velocity[i], &normalrotated);
					sprites.velocity[i] *= 0.3f;

					if (sprites.type[i] == grenadesprite
					    && sprites.size[i] <= 1) {
						auto soundpos = sprites.location[i] - camera.position;
						auto v = findLengthfast(sprites.velocity[i]) * 0.2f;
						ALfloat gLoc[] {
							soundpos.x / v / soundscalefactor,
							soundpos.y / v / soundscalefactor,
							soundpos.z / v / soundscalefactor,
						};
						whichsound = bouncesound + randUint(2);
						alSourcefv(gSourceID[whichsound], AL_POSITION, gLoc);
						alSourcePlay(gSourceID[whichsound]);
					}

					if (findLengthfast(sprites.velocity[i]) <= 10)
						sprites.velocity[i] = {};

				}

				if(sprites.location[i].y<0){
					impact=1;
					sprites.velocity[i].y *= -1.0f;
					sprites.velocity[i] *= 0.3f;
					sprites.location[i].y = 0.0f;

					if(sprites.type[i]==grenadesprite){
						if(sprites.size[i]>1){
							move = {};
							sprites.location[i].y=-.5;
							XYZ normish = {0.0f, 1.0f, 0.0f};
							decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &blocks[citytype[wherex][wherey]], move, 0);
						}

						auto soundpos = sprites.location[i] - camera.position;
						auto v = findLengthfast(sprites.velocity[i]) * 0.2f;
						ALfloat gLoc[] {
							soundpos.x / v / soundscalefactor,
							soundpos.y / v / soundscalefactor,
							soundpos.z / v / soundscalefactor,
						};
						whichsound = bouncesound + randUint(2);
						alSourcefv(gSourceID[whichsound], AL_POSITION, gLoc);
						if (sprites.size[i] <= 1)
							alSourcePlay(gSourceID[whichsound]);

					}

					if (findLengthfast(sprites.velocity[i]) <= 10)
						sprites.velocity[i] = {};

				}

				if(sprites.type[i]==grenadesprite&&findLengthfast(sprites.velocity[i])>20){

					HitStruct hitstruct;

					for(int j=0;j<numpeople;j++){

						if((j!=0||sprites.brightness[i]<.9)&&person[j].existing){

							hitstruct=person[j].BulletCollideWithPlayer(j, sprites.oldlocation[i], sprites.location[i]);

							if(hitstruct.collision){

								impact=1;

								sprites.location[i] = hitstruct.hitlocation;
								auto landpos = sprites.location[i] - camera.position;
								auto v = findLengthfast(sprites.velocity[i]) * 0.2f;
								ALfloat gLoc[] {
									landpos.x / v / soundscalefactor,
									landpos.y / v / soundscalefactor,
									landpos.z / v / soundscalefactor,
								};

								if(person[j].skeleton.free<1){

								if((hitstruct.joint1->label==head||hitstruct.joint2->label==head)&&person[j].type!=zombietype){

									alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);

									if(sprites.size[i]<=1)alSourcePlay(gSourceID[headwhacksound]);

									person[j].skeleton.free=1;

									person[j].longdead=1;

									for (auto& joint : person[j].skeleton.joints) {
										joint.realoldposition = joint.position
											= DoRotation(joint.position,
												0, person[j].playerrotation, 0)
											+ person[j].playercoords;

										joint.velocity = person[j].velocity;
										joint.velocity.x += randInt(-4, 4);
										joint.velocity.y += randInt(-4, 4);
										joint.velocity.z += randInt(-4, 4);
									}

									hitstruct.joint1->velocity += sprites.velocity[i];
									hitstruct.joint2->velocity += sprites.velocity[i];

									if (person[j].type == civiliantype)
										civkills++;
									if (person[j].type == eviltype)
										goodkills++;
								} else {
									float totalarea = 0.0f;

									alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc);

									if(sprites.size[i]<=1)alSourcePlay(gSourceID[bodywhacksound]);

									person[j].skeleton.offset=1;

									for (auto& joint : person[j].skeleton.joints) {
										auto distance = findDistancefast(DoRotation(joint.position, 0, person[j].playerrotation, 0) + person[j].playercoords, hitstruct.hitlocation);
										if (distance < 200) {
											totalarea += 200 / distance;
											joint.offset += DoRotation(sprites.velocity[i] * 0.1 * 200 / distance / totalarea * 10, 0, -person[j].playerrotation, 0);
										}
										if (findLengthfast(joint.offset) > 9) {
											Normalise(&joint.offset);
											joint.offset *= 3;
										}
									}
								}}
								sprites.velocity[i]*=-.3;
							}
						}
					}
				}
				sprites.oldlocation[i]=sprites.location[i];
			}

			//Explode

			if(sprites.type[i]==grenadesprite){

				sprites.brightness[i]-=multiplier*.3;

				if(sprites.brightness[i]<=0||(impact&&sprites.size[i]>1)){
					sprites.brightness[i]=0;
					sprites.MakeSprite(smokesprite, 1, 1, 1, 1, sprites.location[i], facing*0, 60);
					sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, sprites.location[i], facing*0, 9);

					auto explodepos = sprites.location[i]
						- camera.position;
					ALfloat gLoc[] {
						explodepos.x / 3 / soundscalefactor,
						explodepos.y / 3 / soundscalefactor,
						explodepos.z / 3 / soundscalefactor,
					};
					alSourcefv(gSourceID[explosionsound], AL_POSITION, gLoc);
					alSourcePlay(gSourceID[explosionsound]);

					XYZ relation;

					camerashake=1-findDistance(person[0].playercoords,sprites.location[i])/200;

					//if(!sprites.size[i]>1){

						overpoint=sprites.location[i];
						overpoint.y+=3000;
						underpoint=sprites.location[i];
						underpoint.y-=3000;
						wherex=(sprites.location[i].x+block_spacing/2)/block_spacing;
						wherey=(sprites.location[i].z+block_spacing/2)/block_spacing;
						move = {(float) wherex * block_spacing, 0.0f, (float) wherey * block_spacing};


						XYZ temp;

						whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&temp,move,cityrotation[wherex][wherey]*90);

						XYZ normish = {0.0f, 1.0f, 0.0f};
						if(whichtri>=0){

							decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &sidewalkcollide, move, cityrotation[wherex][wherey]*90);

						}

						if(whichtri==-1){
							temp=sprites.location[i];
							temp.y=-.5;
							move = {};
							decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &sidewalkcollide, move, 0);
						}
					//}

					for(int k=0;k<numpeople;k++){

						if(person[k].existing&&(person[k].longdead!=-1||person[k].skeleton.free<1)){

						if((findDistancefast(person[k].playercoords,sprites.location[i])<700&&person[k].skeleton.free<1)||(findDistancefast(person[k].averageloc,sprites.location[i])<700&&person[k].skeleton.free>=1)){

						if(person[k].skeleton.free!=1){

						if(person[k].type==civiliantype)civkills++;

						if(person[k].type==eviltype)goodkills++;

						person[k].skeleton.free=1;

						person[k].killtargetvisible=0;

						if((findDistancefast(person[k].playercoords,sprites.location[i])<600&&person[k].skeleton.free<1)||(findDistancefast(person[k].averageloc,sprites.location[i])<600&&person[k].skeleton.free>=1)||person[k].type==playertype){

							person[k].health-=100;

							person[k].bleeding=1;

						}

						person[k].DoAnimations(k);
						person[k].longdead = 1;
						person[k].bleeddelay = 1;

						person[k].bjoint1 = &person[k].skeleton.joints[head];
						person[k].bjoint2 = &person[k].skeleton.joints[neck];

						for (auto& joint : person[k].skeleton.joints) {
							joint.position = DoRotation(joint.position, 0, person[k].playerrotation, 0);
							joint.position += person[k].playercoords;
							joint.realoldposition = joint.position;
							joint.velocity = DoRotation(joint.velocity, 0, person[k].playerrotation, 0);
							joint.velocity += person[k].velocity;
							joint.velocity.x += randInt(-9, 9);
							joint.velocity.y += randInt(-9, 9);
							joint.velocity.z += randInt(-9, 9);
						}}

						person[k].longdead=1;
						for (auto& joint : person[k].skeleton.joints) {
							relation = joint.position - sprites.location[i];
							Normalise(&relation);
							auto distance = findDistance(joint.position, sprites.location[i]);
							if (distance > 1)
								joint.velocity += relation / distance * 300;
							else
								joint.velocity += relation * 300;

							// Sever stuff
							if (findLengthfast(joint.velocity) > 1500
							    && joint.existing && randUint(5)) {
								sprites.MakeSprite(bloodspritedown, 0.8, 1, 0.2, 0.2, joint.position, joint.velocity / 3, 9);
								person[k].skeleton.DeleteJoint(&joint
									- person[k].skeleton.joints);
								person[k].skeleton.broken=2;
								person[k].health=-10000;
								joint.existing = false;
							}
						}
						}
						}
					}
				}
			}
		}
	}

	//camera shake
	camerashake-=multiplier;
	if(camerashake<0)camerashake=0;

	//camera position
	XYZ average;

	if(!zoom)average=person[0].skeleton.joints[head].position*(person[0].aimamount/2+.5)+person[0].skeleton.joints[neck].position*((1-person[0].aimamount)/2);

	if(zoom)average=person[0].skeleton.joints[righthand].position;

	if(person[0].skeleton.free==0&&thirdperson!=2)camera.position=person[0].playercoords+DoRotation(average,0,person[0].playerrotation,0);

	if(person[0].skeleton.free==1&&thirdperson!=2)camera.position=average;

	//Restraints

	if(camera.position.y<.1)camera.position.y=.1;

	if(thirdperson!=2){
		oldrot=camera.visrotation;
		oldrot2=camera.visrotation2;
	}

	//Kill count
	for(int i=0;i<numpeople;i++){
		if(person[i].oldhealth>0&&person[i].health<=0){
			if(i==1)alSourcePlay(gSourceID[losesound]);
			if(person[i].type==civiliantype){
				alSourcePlay(gSourceID[disguisekillsound]);
				score-=300;
			}

			if(person[i].type==eviltype){
				alSourcePlay(gSourceID[soulinsound]);
				score+=75;
				if(person[i].whichgun==knife)score+=50;
			}
			person[i].firstlongdead=0;
		}
		person[i].oldhealth=person[i].health;
	}

	if(slomo==2){
		psychicpower-=multiplier*15;
		if(psychicpower<0){
			alSourceStop(gSourceID[whichsong]);
			alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
			alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
			if(person[0].whichgun==knife)whichsong=knifesong;
			if(person[0].whichgun!=knife)whichsong=shootsong;
			if(type==zombie_type)whichsong=zombiesong;
			alSourcef(gSourceID[whichsong], AL_PITCH, 1);
			alSourcePlay(gSourceID[whichsong]);
			alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
			alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
			slomo=0;
			alSourcePlay(gSourceID[soulinsound]);
			psychicpower=0;
			flashamount=.5;
			flashr=1;flashg=1;flashb=1;
		}
	}

	psychicpower+=multiplier*5;
	if(psychicpower>10)psychicpower=10;

	setListener(this, facing);
	if (score < 0)
		score = 0;
}