static void G_StateChange_f (void) { if (gi.Cmd_Argc() < 3) { gi.DPrintf("Usage: %s <entnum> <state>\n States are: panic, rage, shaken", gi.Cmd_Argv(0)); return; } const int entnum = atoi(gi.Cmd_Argv(1)); edict_t *e = G_EdictsGetByNum(entnum); if (e == NULL) return; const char *state = gi.Cmd_Argv(2); if (Q_strcasecmp(state, "panic")) { e->morale = mor_panic->integer / 2; } else if (Q_strcasecmp(state, "shaken")) { e->morale = mor_shaken->integer / 2; } else if (Q_strcasecmp(state, "rage")) { e->morale = m_rage->integer / 2; } else { e->morale = 0; } G_MoraleBehaviour(e->team); }
static void G_UseEdict_f (void) { edict_t *e; int i; if (gi.Cmd_Argc() < 2) { gi.DPrintf("Usage: %s <entnum>\n", gi.Cmd_Argv(0)); return; } i = atoi(gi.Cmd_Argv(1)); if (!G_EdictsIsValidNum(i)) { gi.DPrintf("No entity with number %i\n", i); return; } e = G_EdictsGetByNum(i); if (!e->use) { gi.DPrintf("No use function for entity %s\n", e->classname); return; } gi.DPrintf("Call use function for %s\n", e->classname); e->use(e, NULL); }
static void G_TouchEdict_f (void) { edict_t *e, *ent; int i; if (gi.Cmd_Argc() < 2) { gi.DPrintf("Usage: %s <entnum>\n", gi.Cmd_Argv(0)); return; } i = atoi(gi.Cmd_Argv(1)); if (!G_EdictsIsValidNum(i)) return; e = G_EdictsGetByNum(i); if (!e->touch) { gi.DPrintf("No touch function for entity %s\n", e->classname); return; } ent = G_EdictsGetNextLivingActor(NULL); if (!ent) return; /* didn't find any */ gi.DPrintf("Call touch function for %s\n", e->classname); e->touch(e, ent); }
void ReactionFireTargets::notifyClientOnShot (const Edict* target, int tusTarget) { for (int i = 0; i < MAX_RF_DATA; i++) { ReactionFireTargetList* rfts = &rfData[i]; if (rfts->entnum == RF_NO_ENTNUM) continue; const Edict* shooter = G_EdictsGetByNum(rfts->entnum); for (int j = 0; j < rfts->count; j++) { ReactionFireTarget& t = rfts->targets[j]; if (t.target != target) continue; const int tus = std::max(0, target->TU - tusTarget - t.triggerTUs); G_EventReactionFireTargetUpdate(*shooter, *target, tus, MAX_ROUTE); } } }
void ReactionFireTargets::notifyClientMove (const Edict* target, int step, bool startMove) { for (int i = 0; i < MAX_RF_DATA; i++) { ReactionFireTargetList* rfts = &rfData[i]; if (rfts->entnum == RF_NO_ENTNUM) continue; const Edict* shooter = G_EdictsGetByNum(rfts->entnum); for (int j = 0; j < rfts->count; j++) { if (rfts->targets[j].target != target) continue; if (startMove) { const int tus = target->TU - rfts->targets[j].triggerTUs; G_EventReactionFireAddTarget(*shooter, *target, tus, step); } else { G_EventReactionFireRemoveTarget(*shooter, *target, step); } } } }
/** * @brief Do the shooting * @param ent The entity that is doing the shooting * @param teamMask the vis mask to determine the clients from this event is send to * @param fd The firedefinition to use for the shoot * @param firstShoot Is this the first shoot * @param shootType The type of the shoot * @param flags Define some flags in a bitmask: @c SF_BODY, @c SF_IMPACT, @c SF_BOUNCING and @c SF_BOUNCING * @param trace The trace what was used to determine whether this shot has hit something * @param from The position the entity shoots from * @param impact The impact world vector for the shot */ void G_EventShoot (const Edict& ent, teammask_t teamMask, const fireDef_t* fd, bool firstShoot, shoot_types_t shootType, int flags, const trace_t* trace, const vec3_t from, const vec3_t impact) { const Edict* targetEdict = G_EdictsGetByNum(trace->entNum); /* the ent possibly hit by the trace */ G_EventAdd(G_VisToPM(teamMask), EV_ACTOR_SHOOT, ent.number); if (targetEdict && G_IsBreakable(targetEdict)) gi.WriteShort(targetEdict->number); else gi.WriteShort(SKIP_LOCAL_ENTITY); gi.WriteByte(firstShoot ? 1 : 0); gi.WriteShort(fd->obj->idx); gi.WriteByte(fd->weapFdsIdx); gi.WriteByte(fd->fdIdx); gi.WriteByte(shootType); gi.WriteByte(flags); gi.WriteByte(trace->contentFlags); gi.WritePos(from); gi.WritePos(impact); gi.WriteDir(trace->plane.normal); G_EventEnd(); }
static void G_DestroyEdict_f (void) { edict_t *e; int i; if (gi.Cmd_Argc() < 2) { gi.DPrintf("Usage: %s <entnum>\n", gi.Cmd_Argv(0)); return; } i = atoi(gi.Cmd_Argv(1)); if (!G_EdictsIsValidNum(i)) return; e = G_EdictsGetByNum(i); if (!e->destroy) { gi.DPrintf("No destroy function for entity %s\n", e->classname); return; } gi.DPrintf("Call destroy function for %s\n", e->classname); e->destroy(e); }
/** * @brief The client sent us a message that he did something. We now execute the related function(s) and notify him if necessary. * @param[in] player The player to execute the action for (the actor belongs to this player) * @note a client action will also send the server side edict number to determine the actor */ int G_ClientAction (player_t * player) { player_action_t action; int num; pos3_t pos; int i; fireDefIndex_t firemode; int from, fx, fy, to, tx, ty; actorHands_t hand; int fmIdx, objIdx; int resCrouch, resShot; edict_t *ent; const char *format; /* read the header */ action = (player_action_t)gi.ReadByte(); num = gi.ReadShort(); ent = G_EdictsGetByNum(num); if (ent == NULL) return action; format = pa_format[action]; switch (action) { case PA_NULL: /* do nothing on a null action */ break; case PA_TURN: gi.ReadFormat(format, &i); G_ClientTurn(player, ent, (dvec_t) i); break; case PA_MOVE: gi.ReadFormat(format, &pos); G_ClientMove(player, player->pers.team, ent, pos); break; case PA_STATE: gi.ReadFormat(format, &i); G_ClientStateChange(player, ent, i, true); break; case PA_SHOOT: gi.ReadFormat(format, &pos, &i, &firemode, &from); G_ClientShoot(player, ent, pos, i, firemode, NULL, true, from); break; case PA_INVMOVE: gi.ReadFormat(format, &from, &fx, &fy, &to, &tx, &ty); if (from < 0 || from >= gi.csi->numIDs || to < 0 || to >= gi.csi->numIDs) { gi.DPrintf("G_ClientAction: PA_INVMOVE Container index out of range. (from: %i, to: %i)\n", from, to); } else { const invDef_t *fromPtr = INVDEF(from); const invDef_t *toPtr = INVDEF(to); invList_t *fromItem = INVSH_SearchInInventory(&ent->chr.i, fromPtr, fx, fy); if (fromItem) G_ActorInvMove(ent, fromPtr, fromItem, toPtr, tx, ty, true); } break; case PA_USE: if (ent->clientAction) { edict_t *actionEnt; /* read the door the client wants to open */ gi.ReadFormat(format, &i); /* get the door edict */ actionEnt = G_EdictsGetByNum(i); /* maybe the door is no longer 'alive' because it was destroyed */ if (actionEnt && ent->clientAction == actionEnt) { if (G_IsDoor(actionEnt)) { G_ActorUseDoor(ent, actionEnt); } } } break; case PA_REACT_SELECT: gi.ReadFormat(format, &hand, &fmIdx, &objIdx); G_ReactionFireSettingsUpdate(ent, fmIdx, hand, INVSH_GetItemByIDX(objIdx)); break; case PA_RESERVE_STATE: gi.ReadFormat(format, &resShot, &resCrouch); G_ActorReserveTUs(ent, ent->chr.reservedTus.reaction, resShot, resCrouch); break; default: gi.Error("G_ClientAction: Unknown action!\n"); } return action; }