1 /* 2 C-Dogs SDL 3 A port of the legendary (and fun) action/arcade cdogs. 4 Copyright (C) 1995 Ronny Wester 5 Copyright (C) 2003 Jeremy Chin 6 Copyright (C) 2003-2007 Lucas Martin-King 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 22 This file incorporates work covered by the following copyright and 23 permission notice: 24 25 Copyright (c) 2013-2021 Cong Xu 26 All rights reserved. 27 28 Redistribution and use in source and binary forms, with or without 29 modification, are permitted provided that the following conditions are met: 30 31 Redistributions of source code must retain the above copyright notice, this 32 list of conditions and the following disclaimer. 33 Redistributions in binary form must reproduce the above copyright notice, 34 this list of conditions and the following disclaimer in the documentation 35 and/or other materials provided with the distribution. 36 37 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 38 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 41 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 POSSIBILITY OF SUCH DAMAGE. 48 */ 49 #pragma once 50 51 #include "ai_context.h" 52 #include "animation.h" 53 #include "emitter.h" 54 #include "game_mode.h" 55 #include "grafx.h" 56 #include "mathc/mathc.h" 57 #include "player.h" 58 #include "thing.h" 59 #include "weapon.h" 60 61 #define ACTOR_W 14 62 #define ACTOR_H 10 63 64 #define FLAGS_HURTALWAYS (1 << 2) 65 66 // Computer characters only 67 #define FLAGS_DETOURING (1 << 5) 68 #define FLAGS_TRYRIGHT (1 << 6) 69 #define FLAGS_SLEEPING (1 << 7) 70 #define FLAGS_VISIBLE (1 << 8) 71 #define FLAGS_ASBESTOS (1 << 9) // Immune to fire 72 #define FLAGS_IMMUNITY (1 << 10) // Immune to poison 73 #define FLAGS_SEETHROUGH (1 << 11) // Almost transparent 74 #define FLAGS_DEAF (1 << 12) 75 #define FLAGS_WAKING (1 << 13) 76 77 // Special flags 78 #define FLAGS_RUNS_AWAY (1 << 16) // Move directly away from player 79 #define FLAGS_GOOD_GUY (1 << 17) // Shots cannot hurt player 80 #define FLAGS_PRISONER (1 << 18) // Won't move until touched by player 81 #define FLAGS_INVULNERABLE (1 << 19) 82 #define FLAGS_FOLLOWER (1 << 20) // Follows player 83 #define FLAGS_PENALTY (1 << 21) // Big score penalty if shot 84 #define FLAGS_VICTIM (1 << 22) // Can be shot by everyone 85 #define FLAGS_SNEAKY (1 << 23) // Always shoot back when player shoots 86 #define FLAGS_SLEEPALWAYS (1 << 24) 87 #define FLAGS_AWAKEALWAYS (1 << 25) 88 #define FLAGS_RESCUED (1 << 26) // Run towards exit 89 90 typedef enum 91 { 92 ACTORACTION_MOVING, 93 ACTORACTION_EXITING 94 } ActorAction; 95 96 typedef struct Actor 97 { 98 struct vec2 Pos; 99 // Vector that the player is attempting to move in, based on input 100 struct vec2 MoveVel; 101 direction_e direction; 102 // Rotation used to draw the actor, which will lag behind the actual 103 // rotation in order to show smooth rotation 104 float DrawRadians; 105 Animation anim; 106 int stateCounter; 107 int lastCmd; 108 // Whether the player ran into something whilst trying to move 109 // In this situation, we interrupt dead reckoning and resend the position 110 bool hasCollided; 111 // Whether the last special command was performed with a direction 112 // This differentiates between a special command and weapon switch 113 bool specialCmdDir; 114 // If the actor wants to pick up everything, even those that need to be 115 // manually picked up using special input 116 bool PickupAll; 117 // Flag to specify whether this actor is over a special pickup, 118 // such as weapons which will replace the current weapon. 119 // If the player presses switch when in this state, instead of switching 120 // weapons, pick up. 121 bool CanPickupSpecial; 122 123 // -1 if human character (get from player data), otherwise index into 124 // CharacterStore OtherChars 125 int charId; 126 int PlayerUID; // -1 unless a human player 127 int uid; // unique ID across all actors 128 int pilotUID; // the actor that controls this 129 // (same as uid for normal actors) 130 int vehicleUID; // -1 unless piloting a vehicle 131 Weapon guns[MAX_WEAPONS]; 132 CArray ammo; // of int 133 int gunIndex; 134 // TODO: multiple grenade slots? 135 int grenadeIndex; 136 137 int health; 138 // A counter for player death 139 // If 0, player is alive 140 // If >0 but less than deathPics, player is "dying" and this variable 141 // is used as the frame in the death animation 142 int dead; 143 int flamed; 144 int poisoned; 145 int petrified; 146 int confused; 147 int flags; 148 149 int turns; 150 151 int slideLock; 152 // For damage text 153 int accumulatedDamage; 154 // Facial expression when melee or taking damage 155 int grimaceCounter; 156 157 // What to say (text label appears above actor) and how long to say it 158 char Chatter[256]; 159 int ChatterCounter; 160 161 Emitter barrelSmoke; 162 Emitter healEffect; 163 164 // Gore emitters 165 Emitter blood1; 166 Emitter blood2; 167 Emitter blood3; 168 int bleedCounter; 169 170 // Signals to other AIs what this actor is doing 171 ActorAction action; 172 AIContext *aiContext; 173 Thing thing; 174 bool isInUse; 175 } TActor; 176 177 // Store all actors in-line in an array 178 // Destroying actors does not modify the array, only switches 179 // a boolean flag isInUse to denote whether this instance is 180 // in use. 181 // Actors should be identified by index 182 // There is a small chance of invalidating pointers if 183 // actors are added and the array must be resized. 184 // Therefore do not hold actor pointers and reuse. 185 extern CArray gActors; // of TActor 186 187 void ActorSetState(TActor *actor, const ActorAnimation state); 188 void UpdateActorState(TActor *actor, int ticks); 189 bool TryMoveActor(TActor *actor, struct vec2 pos); 190 void ActorMove(const NActorMove am); 191 void CommandActor(TActor *actor, int cmd, int ticks); 192 void SlideActor(TActor *actor, int cmd); 193 void UpdateAllActors(const int ticks); 194 void ActorsPilotVehicles(void); 195 void ActorHeal(TActor *actor, int health); 196 void InjureActor(TActor *actor, int injury); 197 198 void ActorAddAmmo(TActor *actor, const int ammoId, const int amount); 199 // Whether the actor has a gun that uses this ammo 200 bool ActorUsesAmmo(const TActor *actor, const int ammoId); 201 void ActorReplaceGun(const NActorReplaceGun rg); 202 void ActorSetAIState(TActor *actor, const AIState s); 203 void ActorPilot(const NActorPilot ap); 204 205 void ActorsInit(void); 206 void ActorsTerminate(void); 207 int ActorsGetNextUID(void); 208 int ActorsGetFreeIndex(void); 209 TActor *ActorAdd(NActorAdd aa); 210 void ActorDestroy(TActor *a); 211 212 TActor *ActorGetByUID(const int uid); 213 const Character *ActorGetCharacter(const TActor *a); 214 #define ACTOR_GET_GUN(a) (&(a)->guns[(a)->gunIndex]) 215 #define ACTOR_GET_GRENADE(a) (&(a)->guns[(a)->grenadeIndex + MAX_GUNS]) 216 #define ACTOR_GET_WEAPON(a) \ 217 (ACTOR_GET_GUN(a)->Gun != NULL ? ACTOR_GET_GUN(a) : ACTOR_GET_GRENADE(a)) 218 struct vec2 ActorGetAverageWeaponMuzzleOffset(const TActor *a); 219 struct vec2 ActorGetMuzzleOffset( 220 const TActor *a, const Weapon *w, const int barrel); 221 // Returns -1 if gun does not use ammo 222 int ActorWeaponGetAmmo( 223 const TActor *a, const WeaponClass *wc, const int barrel); 224 // Returns -1 if no barrels can fire 225 int ActorGetCanFireBarrel(const TActor *a, const Weapon *w); 226 bool ActorTrySwitchWeapon(const TActor *a, const bool allGuns); 227 // Returns -1 if actor doesn't have gun 228 int ActorFindGun(const TActor *a, const WeaponClass *wc); 229 int ActorGetNumWeapons(const TActor *a); 230 int ActorGetNumGuns(const TActor *a); 231 int ActorGetNumGrenades(const TActor *a); 232 void ActorSwitchGun(const NActorSwitchGun sg); 233 bool ActorIsImmune(const TActor *actor, const special_damage_e damage); 234 bool ActorTakesDamage(const TActor *actor, const special_damage_e damage); 235 void ActorHit(const NThingDamage d); 236 bool ActorIsInvulnerable( 237 const TActor *a, const int flags, const int playerUID, const GameMode mode, 238 const special_damage_e special); 239 240 int ActorGetHealthPercent(const TActor *a); 241 bool ActorIsLowHealth(const TActor *a); 242 bool ActorIsGrimacing(const TActor *a); 243 244 bool ActorIsLocalPlayer(const int uid); 245