static int UTIL_GetNewCheckClient( int check ) { int i; edict_t *ent; Vector org; // cycle to the next one if (check < 1) check = 1; if (check > gpGlobals->maxClients) check = gpGlobals->maxClients; if (check == gpGlobals->maxClients) i = 1; else i = check + 1; for ( ; ; i++) { if ( i > gpGlobals->maxClients ) { i = 1; } ent = INDEXENT( i ); if ( !ent ) continue; // Looped but didn't find anything else if ( i == check ) break; if ( !ent->GetUnknown() ) continue; //CBaseEntity *entity = GetContainingEntity( ent ); CBaseEntity *entity = VFuncs::GetBaseEntity(ent->GetNetworkable()); if ( !entity ) continue; if ( VFuncs::GetFlags(entity) & FL_NOTARGET ) continue; // anything that is a client, or has a client as an enemy break; } if ( i != check ) { memset( g_CheckClient.m_checkVisibilityPVS, 0, sizeof(g_CheckClient.m_checkVisibilityPVS) ); g_CheckClient.m_bClientPVSIsExpanded = false; } if ( ent ) { // get the PVS for the entity //CBaseEntity *pce = GetContainingEntity( ent ); CBaseEntity *pce = VFuncs::GetBaseEntity(ent->GetNetworkable()); if ( !pce ) return i; //org = pce->EyePosition(); org = VFuncs::EyePosition(pce); int clusterIndex = engine->GetClusterForOrigin( org ); if ( clusterIndex != g_CheckClient.m_checkCluster ) { g_CheckClient.m_checkCluster = clusterIndex; engine->GetPVSForCluster( clusterIndex, sizeof(g_CheckClient.m_checkPVS), g_CheckClient.m_checkPVS ); } } return i; }
void NPC::DebugModeMsg(void) { if (FNullEnt(g_hostEntity)) return; if (IsValidPlayer(INDEXENT(g_hostEntity->v.iuser2))) return; char gamemodName[12]; switch (GetGameMode()) { case 0: sprintf(gamemodName, "Normal"); break; case 1: sprintf(gamemodName, "Dm"); break; case 2: sprintf(gamemodName, "ZP"); break; case 3: sprintf(gamemodName, "VS Npc"); break; case 4: sprintf(gamemodName, "ZH"); break; } char taskName[33]; if (m_task & TASK_ENEMY) sprintf(taskName, "TASK_ENEMY"); else if (m_task & TASK_MOVETOTARGET) sprintf(taskName, "TASK_MOVETOTARGET"); else sprintf(taskName, "TASK_NORMAL"); char enemyName[33]; if (!FNullEnt(m_enemy)) strcat(enemyName, GetEntityName(m_enemy)); else if (!FNullEnt(m_moveTargetEntity)) strcat(enemyName, GetEntityName(m_moveTargetEntity)); else strcpy(enemyName, " (null)"); // P.45 - Debugs Mode improve char npcTeam[33]; if (m_npcTeam == 0) sprintf(npcTeam, "TR"); else if (m_npcTeam == 1) sprintf(npcTeam, "CT"); else sprintf(npcTeam, "Team-%d", m_npcTeam); int navIndex[2] = { -1, -1 }; PathNode *navid = &m_navNode[0]; while (navid != null) { if (navIndex[0] == -1) navIndex[0] = navid->index; else if (navIndex[1] == -1) { navIndex[1] = navid->index; break; } navid = navid->next; } char outputBuffer[512]; sprintf(outputBuffer, "\n\n\n\n\n\n\n Game Mode: %s" "\n [%s] \n Task: %s\n" "Enemy: %s Team: %s\n" "CWI: %d GI: %d\n" "Nav: %d Next Nav :%d\n" "Move Speed: %.2f Speed: %.2f\n" "Attack Distance : %.2f" "", gamemodName, GetEntityName(GetEntity()), taskName, enemyName, npcTeam, m_currentWaypointIndex, m_goalWaypoint, navIndex[0], navIndex[1], m_moveSpeed, GetDistance2D(pev->velocity), m_attackDistance); MESSAGE_BEGIN(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, null, g_hostEntity); WRITE_BYTE(TE_TEXTMESSAGE); WRITE_BYTE(1); WRITE_SHORT(FixedSigned16(-1, 1 << 13)); WRITE_SHORT(FixedSigned16(0, 1 << 13)); WRITE_BYTE(0); WRITE_BYTE(255); WRITE_BYTE(100); WRITE_BYTE(255); WRITE_BYTE(0); WRITE_BYTE(255); WRITE_BYTE(255); WRITE_BYTE(255); WRITE_BYTE(0); WRITE_SHORT(FixedUnsigned16(0, 1 << 8)); WRITE_SHORT(FixedUnsigned16(0, 1 << 8)); WRITE_SHORT(FixedUnsigned16(1.0, 1 << 8)); WRITE_STRING(const_cast <const char *> (&outputBuffer[0])); MESSAGE_END(); if (!FNullEnt (m_enemy)) DrawLine(g_hostEntity, pev->origin, GetEntityOrigin (m_enemy), Color(255, 0, 0, 200), 10, 0, 5, 1, LINE_SIMPLE); if (!FNullEnt (m_moveTargetEntity)) DrawLine(g_hostEntity, pev->origin, GetEntityOrigin (m_moveTargetEntity), Color(0, 255, 0, 200), 10, 0, 5, 1, LINE_SIMPLE); PathNode *node = &m_navNode[0]; Vector src = nullvec; while (node != null) { int wpIndex = node->index; src = g_waypoint->g_waypointPointOrigin[node->index]; node = node->next; if (node != null) { bool jumpPoint = false; for (int j = 0; j < Const_MaxPathIndex; j++) { if (g_waypoint->g_wpConnectionIndex[wpIndex][j] != node->index) continue; if (g_waypoint->g_wpConnectionFlags[wpIndex][j] & PATHFLAG_JUMP) { jumpPoint = true; break; } } if (!jumpPoint) DrawLine(g_hostEntity, src, g_waypoint->g_waypointPointOrigin[node->index], Color(255, 100, 55, 20), 15, 0, 8, 1, LINE_SIMPLE); else DrawLine(g_hostEntity, src, g_waypoint->g_waypointPointOrigin[node->index], Color(255, 0, 0, 20), 15, 0, 8, 1, LINE_SIMPLE); } else DrawLine(g_hostEntity, src, src + Vector(0, 0, 40), Color(255, 255, 255, 100), 15, 0, 8, 1, LINE_SIMPLE); } if (g_waypoint->GetEntityWpIndex(GetEntity()) != -1) { src = g_waypoint->g_waypointPointOrigin[g_waypoint->GetEntityWpIndex(GetEntity())]; DrawLine(g_hostEntity, src, src + Vector(0, 0, 40), Color(255, 0, 0, 100), 15, 0, 8, 1, LINE_SIMPLE); } if (m_currentWaypointIndex != -1) { src = g_waypoint->g_waypointPointOrigin[m_currentWaypointIndex]; DrawLine(g_hostEntity, src, src + Vector(0, 0, 40), Color(0, 255, 0, 100), 15, 0, 8, 1, LINE_SIMPLE); } if (m_waypointOrigin != nullvec) { src = m_waypointOrigin; DrawLine(g_hostEntity, src, src + Vector(0, 0, 40), Color(255, 0, 255, 100), 15, 0, 8, 1, LINE_SIMPLE); } if (m_goalWaypoint != -1) { src = g_waypoint->g_waypointPointOrigin[m_goalWaypoint]; DrawLine(g_hostEntity, src, src + Vector(0, 0, 40), Color(0, 0, 255, 100), 15, 0, 8, 1, LINE_SIMPLE); } }
void CC_CollisionTest( const CCommand &args ) { if ( !physenv ) return; Msg( "Testing collision system\n" ); int i; CBaseEntity *pSpot = gEntList.FindEntityByClassname( NULL, "info_player_start"); Vector start = pSpot->GetAbsOrigin(); static Vector *targets = NULL; static bool first = true; static float test[2] = {1,1}; if ( first ) { targets = new Vector[NUM_COLLISION_TESTS]; float radius = 0; float theta = 0; float phi = 0; for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) { radius += NUM_COLLISION_TESTS * 123.123; radius = fabs(fmod(radius, 128)); theta += NUM_COLLISION_TESTS * 76.76; theta = fabs(fmod(theta, DEG2RAD(360))); phi += NUM_COLLISION_TESTS * 1997.99; phi = fabs(fmod(phi, DEG2RAD(180))); float st, ct, sp, cp; SinCos( theta, &st, &ct ); SinCos( phi, &sp, &cp ); targets[i].x = radius * ct * sp; targets[i].y = radius * st * sp; targets[i].z = radius * cp; // make the trace 1024 units long Vector dir = targets[i] - start; VectorNormalize(dir); targets[i] = start + dir * 1024; } first = false; } //Vector results[NUM_COLLISION_TESTS]; int testType = 0; if ( args.ArgC() >= 2 ) { testType = atoi( args[1] ); } float duration = 0; Vector size[2]; size[0].Init(0,0,0); size[1].Init(16,16,16); unsigned int dots = 0; for ( int j = 0; j < 2; j++ ) { float startTime = engine->Time(); if ( testType == 1 ) { const CPhysCollide *pCollide = g_PhysWorldObject->GetCollide(); trace_t tr; for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) { physcollision->TraceBox( start, targets[i], -size[j], size[j], pCollide, vec3_origin, vec3_angle, &tr ); dots += physcollision->ReadStat(0); //results[i] = tr.endpos; } } else { testType = 0; CBaseEntity *pWorld = GetContainingEntity( INDEXENT(0) ); trace_t tr; for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) { UTIL_TraceModel( start, targets[i], -size[j], size[j], pWorld, COLLISION_GROUP_NONE, &tr ); //results[i] = tr.endpos; } } duration += engine->Time() - startTime; } test[testType] = duration; Msg("%d collisions in %.2f ms (%u dots)\n", NUM_COLLISION_TESTS, duration*1000, dots ); Msg("Current speed ratio: %.2fX BSP:JGJK\n", test[1] / test[0] ); #if 0 int red = 255, green = 0, blue = 0; for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) { NDebugOverlay::Line( start, results[i], red, green, blue, false, 2 ); } #endif }
// time to think about something new to do void CHLDMBot :: getTasks (unsigned int iIgnore) { static CBotUtilities utils; static CBotUtility *next; static CBotWeapon *gravgun; static CBotWeapon *crossbow; static CWeapon *pWeapon; static bool bCheckCurrent; if ( !hasSomeConditions(CONDITION_CHANGED) && !m_pSchedules->isEmpty() ) return; removeCondition(CONDITION_CHANGED); bCheckCurrent = true; // important for checking current schedule gravgun = m_pWeapons->getWeapon(CWeapons::getWeapon(HL2DM_WEAPON_PHYSCANNON)); // If I have the grav gun, think about picking something up if ( gravgun ) { edict_t *pent = INDEXENT(gravgun->getWeaponIndex()); if ( CBotGlobals::entityIsValid(pent) ) { ADD_UTILITY(BOT_UTIL_HL2DM_GRAVIGUN_PICKUP,(!m_pEnemy||(m_pCurrentWeapon&&(strcmp("weapon_physcannon",m_pCurrentWeapon->GetClassName())))) && gravgun && gravgun->hasWeapon() && (m_NearestPhysObj.get()!=NULL) && (gravgun->getWeaponIndex() > 0) && (CClassInterface::gravityGunObject(INDEXENT(gravgun->getWeaponIndex()))==NULL),0.9f); } } if ( (crossbow = m_pWeapons->getWeapon(CWeapons::getWeapon(HL2DM_WEAPON_CROSSBOW))) != NULL ) { if ( crossbow->hasWeapon() && !crossbow->outOfAmmo(this) ) ADD_UTILITY(BOT_UTIL_SNIPE,true,0.91f); } // low on health? Pick some up if there's any near by ADD_UTILITY(BOT_UTIL_HL2DM_USE_HEALTH_CHARGER,(m_pHealthCharger.get() != NULL) && (CClassInterface::getAnimCycle(m_pHealthCharger)<1.0f) && (getHealthPercent()<1.0f),(1.0f-getHealthPercent())); ADD_UTILITY(BOT_UTIL_FIND_NEAREST_HEALTH,(m_pHealthKit.get()!=NULL) && (getHealthPercent()<1.0f),1.0f-getHealthPercent()); // low on armor? ADD_UTILITY(BOT_UTIL_HL2DM_FIND_ARMOR,(m_pBattery.get() !=NULL) && (getArmorPercent()<1.0f),(1.0f-getArmorPercent())*0.75f); ADD_UTILITY(BOT_UTIL_HL2DM_USE_CHARGER,(m_pCharger.get() !=NULL) && (CClassInterface::getAnimCycle(m_pCharger)<1.0f) && (getArmorPercent()<1.0f),(1.0f-getArmorPercent())*0.75f); ADD_UTILITY(BOT_UTIL_HL2DM_USE_CRATE,(m_pAmmoCrate.get()!=NULL) && (m_fUseCrateTime < engine->Time()),1.0f); // low on ammo? ammo nearby? ADD_UTILITY(BOT_UTIL_FIND_NEAREST_AMMO,(m_pAmmoKit.get() !=NULL) && (getAmmo(0)<5),0.01f*(100-getAmmo(0))); // always able to roam around ADD_UTILITY(BOT_UTIL_ROAM,true,0.01f); // I have an enemy ADD_UTILITY(BOT_UTIL_FIND_LAST_ENEMY,wantToFollowEnemy() && !m_bLookedForEnemyLast && m_pLastEnemy && CBotGlobals::entityIsValid(m_pLastEnemy) && CBotGlobals::entityIsAlive(m_pLastEnemy),getHealthPercent()*(getArmorPercent()+0.1)); if ( !hasSomeConditions(CONDITION_SEE_CUR_ENEMY) && hasSomeConditions(CONDITION_SEE_LAST_ENEMY_POS) && m_pLastEnemy && m_fLastSeeEnemy && ((m_fLastSeeEnemy + 10.0) > engine->Time()) && m_pWeapons->hasWeapon(HL2DM_WEAPON_FRAG) ) { float fDistance = distanceFrom(m_vLastSeeEnemyBlastWaypoint); if ( ( fDistance > BLAST_RADIUS ) && ( fDistance < 1500 ) ) { CWeapon *pWeapon = CWeapons::getWeapon(HL2DM_WEAPON_FRAG); CBotWeapon *pBotWeapon = m_pWeapons->getWeapon(pWeapon); ADD_UTILITY(BOT_UTIL_THROW_GRENADE, pBotWeapon && (pBotWeapon->getAmmo(this) > 0) ,1.0f-(getHealthPercent()*0.2)); } } if ( m_pNearbyWeapon.get() ) { pWeapon = CWeapons::getWeapon(m_pNearbyWeapon.get()->GetClassName()); if ( pWeapon && !m_pWeapons->hasWeapon(pWeapon->getID()) ) { ADD_UTILITY(BOT_UTIL_PICKUP_WEAPON, true , 0.6f + pWeapon->getPreference()*0.1f); } } utils.execute(); while ( (next = utils.nextBest()) != NULL ) { if ( !m_pSchedules->isEmpty() && bCheckCurrent ) { if ( m_CurrentUtil != next->getId() ) m_pSchedules->freeMemory(); else break; } bCheckCurrent = false; if ( executeAction(next->getId()) ) { m_CurrentUtil = next->getId(); if ( m_fUtilTimes[next->getId()] < engine->Time() ) m_fUtilTimes[next->getId()] = engine->Time() + randomFloat(0.1f,2.0f); // saves problems with consistent failing if ( CClients::clientsDebugging(BOT_DEBUG_UTIL) ) { CClients::clientDebugMsg(BOT_DEBUG_UTIL,g_szUtils[next->getId()],this); } break; } } utils.freeMemory(); }
bool RadioCreate( edict_t *pEntity ) { // Create the radio and stick to the wall entvars_t *pPev = VARS( pEntity ); if (pPev->iuser1 > 0) return 0; // make sure we dont already have a radio int radiocount = 0; int i = 1; char *pClassname; edict_t *frontEnt; for (i; i < 1025; i++) { frontEnt = INDEXENT ( i ); if (frontEnt) { pClassname = (char *)STRING(frontEnt->v.classname); if (FStrEq("building_radio", pClassname)) { if (frontEnt->v.euser4 == pEntity) { radiocount++; } } } } if (AdminLoggedIn[ENTINDEX(pEntity)] == 0) { if (radiocount >= 2) { ClientPrint( pPev, HUD_PRINTTALK, "* Cant have more than 2 radios!\n"); return 0; } } UTIL_MakeVectors( pPev->v_angle + pPev->punchangle ); Vector vecSrc = GetGunPosition( pEntity ); Vector vecAiming = gpGlobals->v_forward; TraceResult tr; UTIL_TraceLine( vecSrc, vecSrc + vecAiming * 128, dont_ignore_monsters, pEntity , &tr ); if (tr.flFraction < 1.0 || AdminLoggedIn[ENTINDEX(pEntity)]) { if (tr.pHit && !(tr.pHit->v.flags & FL_CONVEYOR) && (FStrEq((char *)STRING(tr.pHit->v.classname), "worldspawn") || FStrEq((char *)STRING(tr.pHit->v.classname), "func_wall") || AdminLoggedIn[ENTINDEX(pEntity)] || FStrEq((char *)STRING(tr.pHit->v.classname), "building_dancemachine"))) // Make sure it isnt a conveyor! { Vector angles = UTIL_VecToAngles( tr.vecPlaneNormal ); if ((angles.x > 30 || angles.x < -30) && AdminLoggedIn[ENTINDEX(pEntity)] == 0) { ClientPrint( pPev, HUD_PRINTTALK, "* Can't place radios on floors or cielings!\n"); return 0; } // Create the camera here! Vector vecOri = tr.vecEndPos + tr.vecPlaneNormal * 14; //Vector vecOri = tr.vecEndPos + tr.vecPlaneNormal * 15; int maxdist = (int)CVAR_GET_FLOAT("sa_radiospread"); // make sure we arent placing it within 400 units of another radio for (i=1; i < 1025; i++) { frontEnt = INDEXENT ( i ); if (frontEnt) { pClassname = (char *)STRING(frontEnt->v.classname); if (FStrEq("building_radio", pClassname)) { if ((frontEnt->v.origin - vecOri).Length() < maxdist && AdminLoggedIn[ENTINDEX(pEntity)] == 0) { ClientPrint( pPev, HUD_PRINTTALK, "* Can't place a radio so close to another radio!\n"); return 0; } } } } KeyValueData kvd; //edict_t *pent = CREATE_ENTITY(); //edict_t *pent = CREATE_NAMED_ENTITY(MAKE_STRING("info_target")); edict_t *tEntity; tEntity = CREATE_NAMED_ENTITY(MAKE_STRING("info_target")); entvars_t *pRunOnPev; pRunOnPev = VARS(tEntity); char buf[80]; sprintf( buf, "%s", "building_radio"); // Set the KEYVALUES here! kvd.fHandled = FALSE; kvd.szClassName = NULL; kvd.szKeyName = "classname"; kvd.szValue = buf; DispatchKeyValue( tEntity, &kvd ); // place this in front pRunOnPev->origin = vecOri; SET_ORIGIN( tEntity , vecOri ); pRunOnPev->angles = angles; //DispatchSpawn( ENT( pRunOnPev ) ); pRunOnPev->solid = SOLID_BBOX; SET_MODEL( ENT( pRunOnPev ) , "avatar-x/avadd16.avfil"); UTIL_SetSize( pRunOnPev, Vector( -2, -2 ,-2) - (tr.vecPlaneNormal * 15), Vector(2, 2, 16) - (tr.vecPlaneNormal * 15)); pRunOnPev->takedamage = DAMAGE_YES; pRunOnPev->max_health = 40 + 10000; pRunOnPev->health = 40 + 10000; pRunOnPev->euser4 = pEntity; /* edict_t *pent; pent = CREATE_NAMED_ENTITY(MAKE_STRING("xen_tree")); entvars_t *pv = VARS( pent ); pv->origin = vecOri; SET_ORIGIN(pent, vecOri); kvd.fHandled = FALSE; kvd.szClassName = NULL; kvd.szKeyName = "classname"; kvd.szValue = "xen_tree"; DispatchKeyValue( pent, &kvd ); DispatchSpawn(pent); //pev->angles = angles; */ //pev->iuser1 = angles.y; //pv->vuser3 = angles; // for now don't take damage //pev->takedamage = DAMAGE_YES; //pev->max_health = 40 + 10000; //pev->health = 40 + 10000; /* // Call the SPAWN routine to set more stuff kvd.fHandled = FALSE; kvd.szClassName = NULL; kvd.szKeyName = "classname"; kvd.szValue = "building_radio"; //DispatchKeyValue( pent, &kvd ); kvd.fHandled = FALSE; */ RadioSpawn( tEntity ); return 1; } else { ClientPrint( pPev, HUD_PRINTTALK, "* Couldn't place radio here!\n"); return 0; } } else { ClientPrint( pPev, HUD_PRINTTALK, "* Couldn't place radio here!\n"); } return 0; }
// Float:set_controller(entid, controllerid, Float:value); static cell AMX_NATIVE_CALL set_controller(AMX* amx, cell* params) { // From animation.cpp from the HLSDK // SetController( void *pmodel, entvars_t *pev, int iController, float flValue ) int entindex = params[1]; CHECK_ENTITY(entindex); edict_t* entity = INDEXENT(entindex); int iController = params[2]; if (iController < 0 || iController > 3) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid controller id passed. Expected 0 through 3, got %d.", iController); return 0; } entvars_t* pev = &entity->v; float flValue = amx_ctof(params[3]); studiohdr_t* pstudiohdr = static_cast<studiohdr_t*>(GET_MODEL_PTR(entity)); if (! pstudiohdr) { MF_LogError(amx, AMX_ERR_NATIVE, "Could not find the model pointer for the entity."); return amx_ftoc(flValue); } mstudiobonecontroller_t *pbonecontroller = (mstudiobonecontroller_t *)((byte *)pstudiohdr + pstudiohdr->bonecontrollerindex); int i = 0; // find first controller that matches the index for (i = 0; i < pstudiohdr->numbonecontrollers; i++, pbonecontroller++) { if (pbonecontroller->index == iController) break; } if (i >= pstudiohdr->numbonecontrollers) return amx_ftoc(flValue); // wrap 0..360 if it's a rotational controller if (pbonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR)) { // ugly hack, invert value if end < start if (pbonecontroller->end < pbonecontroller->start) flValue = -flValue; // does the controller not wrap? if (pbonecontroller->start + 359.0 >= pbonecontroller->end) { if (flValue > ((pbonecontroller->start + pbonecontroller->end) / 2.0) + 180) flValue = flValue - 360; if (flValue < ((pbonecontroller->start + pbonecontroller->end) / 2.0) - 180) flValue = flValue + 360; } else { if (flValue > 360) flValue = flValue - (int)(flValue / 360.0) * 360.0; else if (flValue < 0) flValue = flValue + (int)((flValue / -360.0) + 1) * 360.0; } } int setting = static_cast<int>(255 * (flValue - pbonecontroller->start) / (pbonecontroller->end - pbonecontroller->start)); if (setting < 0) setting = 0; if (setting > 255) setting = 255; pev->controller[iController] = setting; return amx_ftoc(setting * (1.0 / 255.0) * (pbonecontroller->end - pbonecontroller->start) + pbonecontroller->start); }
// Picks a random name // rewritten on april 10th 2004 void cGame::SelectName(char *name) { int iNameIndex, iIndex; bool bUsed; edict_t *pPlayer; iNameIndex = 0; // zero based (RANDOM_LONG (0, iAmountNames-1)) bool iNameUsed[MAX_BOT_NAMES]; for (int i = 0; i < MAX_BOT_NAMES; i++) { iNameUsed[i] = false; } // check make sure this name isn't used bUsed = true; while (bUsed) { iNameIndex = RANDOM_LONG(0, iAmountNames - 1); // pick random one int iLimit = iNameIndex; // remember this. // make sure it is not checked yet while (iNameUsed[iNameIndex]) { // check again if (iNameUsed[iNameIndex] == false) break; // add up iNameIndex++; // make sure that it does not check out of range if (iNameIndex == iAmountNames) iNameIndex = 0; // go to 0 (will be set to 0 next 'name') // when we are back to where we came from, get the f**k outta here if (iNameIndex == iLimit) { strcpy(name, "RealBot"); return; } } // so far we did not find evidence that this name has been used already bUsed = false; // check if this name is used for (iIndex = 1; iIndex <= gpGlobals->maxClients; iIndex++) { pPlayer = INDEXENT(iIndex); if (pPlayer && !pPlayer->free) { if (strcmp(cBotNames[iNameIndex], STRING(pPlayer->v.netname)) == 0) { // atten tion, this namehas been used. bUsed = true; break; } } } if (bUsed) iNameUsed[iNameIndex] = true; // set on true } // copy name into the name_buffer strcpy(name, cBotNames[iNameIndex]); } // SelectName()
void NetworkMsg::Execute (void *p) { if (m_message == NETMSG_UNDEFINED) return; // no message or not for bot, return // some needed variables static uint8_t r, g, b; static uint8_t enabled; static int damageArmor, damageTaken, damageBits; static int killerIndex, victimIndex, playerIndex; static int index, numPlayers; static int state, id, clip; static Vector damageOrigin; static WeaponProperty weaponProp; // now starts of netmessage execution switch (m_message) { case NETMSG_VGUI: // this message is sent when a VGUI menu is displayed. if (m_state == 0) { switch (PTR_TO_INT (p)) { case GMENU_TEAM: m_bot->m_startAction = CMENU_TEAM; break; case GMENU_TERRORIST: case GMENU_COUNTER: m_bot->m_startAction = CMENU_CLASS; break; } } break; case NETMSG_SHOWMENU: // this message is sent when a text menu is displayed. if (m_state < 3) // ignore first 3 fields of message break; if (strcmp (PTR_TO_STR (p), "#Team_Select") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#Team_Select_Spect") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select_Spect") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select_Spect") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#Terrorist_Select") == 0) // T model select? m_bot->m_startAction = CMENU_CLASS; else if (strcmp (PTR_TO_STR (p), "#CT_Select") == 0) // CT model select menu? m_bot->m_startAction = CMENU_CLASS; break; case NETMSG_WLIST: // this message is sent when a client joins the game. All of the weapons are sent with the weapon ID and information about what ammo is used. switch (m_state) { case 0: strcpy (weaponProp.className, PTR_TO_STR (p)); break; case 1: weaponProp.ammo1 = PTR_TO_INT (p); // ammo index 1 break; case 2: weaponProp.ammo1Max = PTR_TO_INT (p); // max ammo 1 break; case 5: weaponProp.slotID = PTR_TO_INT (p); // slot for this weapon break; case 6: weaponProp.position = PTR_TO_INT (p); // position in slot break; case 7: weaponProp.id = PTR_TO_INT (p); // weapon ID break; case 8: weaponProp.flags = PTR_TO_INT (p); // flags for weapon (WTF???) g_weaponDefs[weaponProp.id] = weaponProp; // store away this weapon with it's ammo information... break; } break; case NETMSG_CURWEAPON: // this message is sent when a weapon is selected (either by the bot chosing a weapon or by the server auto assigning the bot a weapon). In CS it's also called when Ammo is increased/decreased switch (m_state) { case 0: state = PTR_TO_INT (p); // state of the current weapon (WTF???) break; case 1: id = PTR_TO_INT (p); // weapon ID of current weapon break; case 2: clip = PTR_TO_INT (p); // ammo currently in the clip for this weapon if (id <= 31) { if (state != 0) m_bot->m_currentWeapon = id; // ammo amount decreased ? must have fired a bullet... if (id == m_bot->m_currentWeapon && m_bot->m_ammoInClip[id] > clip) { // time fired with in burst firing time ? if (m_bot->m_timeLastFired + 1.0f > engine->GetTime ()) m_bot->m_burstShotsFired++; m_bot->m_timeLastFired = engine->GetTime (); // remember the last bullet time } m_bot->m_ammoInClip[id] = clip; } break; } break; case NETMSG_AMMOX: // this message is sent whenever ammo amounts are adjusted (up or down). NOTE: Logging reveals that CS uses it very unreliable! switch (m_state) { case 0: index = PTR_TO_INT (p); // ammo index (for type of ammo) break; case 1: m_bot->m_ammo[index] = PTR_TO_INT (p); // store it away break; } break; case NETMSG_AMMOPICK: // this message is sent when the bot picks up some ammo (AmmoX messages are also sent so this message is probably // not really necessary except it allows the HUD to draw pictures of ammo that have been picked up. The bots // don't really need pictures since they don't have any eyes anyway. switch (m_state) { case 0: index = PTR_TO_INT (p); break; case 1: m_bot->m_ammo[index] = PTR_TO_INT (p); break; } break; case NETMSG_DAMAGE: // this message gets sent when the bots are getting damaged. switch (m_state) { case 0: damageArmor = PTR_TO_INT (p); break; case 1: damageTaken = PTR_TO_INT (p); break; case 2: damageBits = PTR_TO_INT (p); if (damageArmor > 0 || damageTaken > 0) m_bot->TakeDamage (m_bot->pev->dmg_inflictor, damageTaken, damageArmor, damageBits); break; } break; case NETMSG_MONEY: // this message gets sent when the bots money amount changes if (m_state == 0) m_bot->m_moneyAmount = PTR_TO_INT (p); // amount of money break; case NETMSG_STATUSICON: switch (m_state) { case 0: enabled = PTR_TO_BYTE (p); break; case 1: if (strcmp (PTR_TO_STR (p), "defuser") == 0) m_bot->m_hasDefuser = (enabled != 0); else if (strcmp (PTR_TO_STR (p), "buyzone") == 0) { m_bot->m_inBuyZone = (enabled != 0); // try to equip in buyzone m_bot->EquipInBuyzone (0); } else if (strcmp (PTR_TO_STR (p), "vipsafety") == 0) m_bot->m_inVIPZone = (enabled != 0); else if (strcmp (PTR_TO_STR (p), "c4") == 0) m_bot->m_inBombZone = (enabled == 2); break; } break; case NETMSG_DEATH: // this message sends on death switch (m_state) { case 0: killerIndex = PTR_TO_INT (p); break; case 1: victimIndex = PTR_TO_INT (p); break; case 2: if (killerIndex != 0 && killerIndex != victimIndex) { edict_t *killer = INDEXENT (killerIndex); edict_t *victim = INDEXENT (victimIndex); if (FNullEnt (killer) || FNullEnt (victim)) break; // need to send congrats on well placed shot for (int i = 0; i < engine->GetMaxClients (); i++) { Bot *bot = g_botManager->GetBot (i); if (bot != null && IsAlive (bot->GetEntity ()) && killer != bot->GetEntity () && bot->EntityIsVisible (victim->v.origin) && GetTeam (killer) == GetTeam (bot->GetEntity ()) && GetTeam (killer) != GetTeam (victim)) { if (killer == g_hostEntity) bot->HandleChatterMessage ("#Bot_NiceShotCommander"); else bot->HandleChatterMessage ("#Bot_NiceShotPall"); break; } } // SyPB Pro P.15 if (GetGameMod () == 0) { // notice nearby to victim teammates, that attacker is near for (int i = 0; i < engine->GetMaxClients (); i++) { Bot *bot = g_botManager->GetBot (i); if (bot != null && IsAlive (bot->GetEntity ()) && GetTeam (bot->GetEntity ()) == GetTeam (victim) && IsVisible (killer->v.origin, bot->GetEntity ()) && FNullEnt (bot->m_enemy) && GetTeam (killer) != GetTeam (victim)) { bot->m_actualReactionTime = 0.0f; bot->m_seeEnemyTime = engine->GetTime (); bot->m_enemy = killer; bot->m_lastEnemy = killer; bot->m_lastEnemyOrigin = killer->v.origin; } } } Bot *bot = g_botManager->GetBot (killer); // is this message about a bot who killed somebody? if (bot != null) bot->m_lastVictim = victim; else // did a human kill a bot on his team? { Bot *iter = g_botManager->GetBot (victim); if (iter != null) { if (GetTeam (killer) == GetTeam (victim)) iter->m_voteKickIndex = killerIndex; iter->m_notKilled = false; } } } break; } break; case NETMSG_SCREENFADE: // this message gets sent when the Screen fades (Flashbang) switch (m_state) { case 3: r = PTR_TO_BYTE (p); break; case 4: g = PTR_TO_BYTE (p); break; case 5: b = PTR_TO_BYTE (p); break; case 6: m_bot->TakeBlinded (Vector (r, g, b), PTR_TO_BYTE (p)); break; } break; case NETMSG_HLTV: // round restart in steam cs switch (m_state) { case 0: numPlayers = PTR_TO_INT (p); break; case 1: if (numPlayers == 0 && PTR_TO_INT (p) == 0) RoundInit (); break; } break; case NETMSG_RESETHUD: #if 0 if (m_bot != null) m_bot->NewRound (); #endif break; case NETMSG_TEXTMSG: if (m_state == 1) { if (FStrEq (PTR_TO_STR (p), "#CTs_Win") || FStrEq (PTR_TO_STR (p), "#Bomb_Defused") || FStrEq (PTR_TO_STR (p), "#Terrorists_Win") || FStrEq (PTR_TO_STR (p), "#Round_Draw") || FStrEq (PTR_TO_STR (p), "#All_Hostages_Rescued") || FStrEq (PTR_TO_STR (p), "#Target_Saved") || FStrEq (PTR_TO_STR (p), "#Hostages_Not_Rescued") || FStrEq (PTR_TO_STR (p), "#Terrorists_Not_Escaped") || FStrEq (PTR_TO_STR (p), "#VIP_Not_Escaped") || FStrEq (PTR_TO_STR (p), "#Escaping_Terrorists_Neutralized") || FStrEq (PTR_TO_STR (p), "#VIP_Assassinated") || FStrEq (PTR_TO_STR (p), "#VIP_Escaped") || FStrEq (PTR_TO_STR (p), "#Terrorists_Escaped") || FStrEq (PTR_TO_STR (p), "#CTs_PreventEscape") || FStrEq (PTR_TO_STR (p), "#Target_Bombed") || FStrEq (PTR_TO_STR (p), "#Game_Commencing") || FStrEq (PTR_TO_STR (p), "#Game_will_restart_in")) { g_roundEnded = true; if (FStrEq (PTR_TO_STR (p), "#Game_Commencing")) g_isCommencing = true; if (FStrEq (PTR_TO_STR (p), "#CTs_Win")) g_botManager->SetLastWinner (TEAM_COUNTER); // update last winner for economics if (FStrEq (PTR_TO_STR (p), "#Terrorists_Win")) g_botManager->SetLastWinner (TEAM_TERRORIST); // update last winner for economics g_waypoint->SetBombPosition (true); } else if (!g_bombPlanted && FStrEq (PTR_TO_STR (p), "#Bomb_Planted")) { g_bombPlanted = true; g_bombSayString = true; g_timeBombPlanted = engine->GetTime (); for (int i = 0; i < engine->GetMaxClients (); i++) { Bot *bot = g_botManager->GetBot (i); if (bot != null && IsAlive (bot->GetEntity ())) { bot->DeleteSearchNodes (); bot->ResetTasks (); if (engine->RandomInt (0, 100) < 85 && GetTeam (bot->GetEntity ()) == TEAM_COUNTER) bot->ChatterMessage (Chatter_WhereIsTheBomb); } } g_waypoint->SetBombPosition (); } else if (m_bot != null && FStrEq (PTR_TO_STR (p), "#Switch_To_BurstFire")) m_bot->m_weaponBurstMode = BURST_ENABLED; else if (m_bot != null && FStrEq (PTR_TO_STR (p), "#Switch_To_SemiAuto")) m_bot->m_weaponBurstMode = BURST_DISABLED; } break; case NETMSG_SCOREINFO: switch (m_state) { case 0: playerIndex = PTR_TO_INT (p); break; case 4: if (playerIndex >= 0 && playerIndex <= engine->GetMaxClients ()) { if (PTR_TO_INT (p) == 1) g_clients[playerIndex - 1].realTeam = TEAM_TERRORIST; else if (PTR_TO_INT (p) == 2) g_clients[playerIndex - 1].realTeam = TEAM_COUNTER; g_clients[playerIndex - 1].team = g_clients[playerIndex - 1].realTeam; } break; } break; case NETMSG_BARTIME: if (m_state == 0) { if (PTR_TO_INT (p) > 0) m_bot->m_hasProgressBar = true; // the progress bar on a hud else if (PTR_TO_INT (p) == 0) m_bot->m_hasProgressBar = false; // no progress bar or disappeared } break; default: AddLogEntry (true, LOG_FATAL, "Network message handler error. Call to unrecognized message id (%d).\n", m_message); } m_state++; // and finally update network message state }
void DanceThink ( edict_t *pent ) { entvars_t *pev = VARS(pent); if (pev->iuser2 > 0 && pev->fuser3 == 0) { // rotate position double ang = (double)pev->iuser3 + (double)pev->fuser1; double newx = (double)pev->vuser1.x + cos(ang * (3.14159 / 180)) * (double)pev->iuser1; double newy = (double)pev->vuser1.y + sin(ang * (3.14159 / 180)) * (double)pev->iuser1; if (ang > 360) ang = ang - 360; if (ang < 0) ang = ang + 360; pev->iuser3 = (int)ang; // set origin Vector newOri; newOri.x = newx; newOri.y = newy; newOri.z = pev->origin.z; //SET_ORIGIN(pent, newOri); Vector MoveVec = newOri - pev->origin; pev->velocity = MoveVec; } if (pev->iuser4 > 0) { // center on ent edict_t *pen = INDEXENT(pev->iuser4); if (pen && !FNullEnt(pen)) { pev->vuser1 = pen->v.origin; Vector lookVec = pen->v.origin - pev->origin; //lookVec.Normalize; lookVec = UTIL_VecToAngles(lookVec); lookVec.x = -lookVec.x; Vector goVec = (lookVec - pev->angles); while (goVec.x > 360) goVec.x = goVec.x - 360; while (goVec.x < 0) goVec.x = goVec.x + 360; while (goVec.y > 360) goVec.y = goVec.y - 360; while (goVec.y < 0) goVec.y = goVec.y + 360; while (goVec.z > 360) goVec.z = goVec.z - 360; while (goVec.z < 0) goVec.z = goVec.z + 360; if (goVec.x > 180) goVec.x = -(360 - goVec.x); if (goVec.x < -180) goVec.x = (360 + goVec.x); if (goVec.y > 180) goVec.y = -(360 - goVec.y); if (goVec.y < -180) goVec.y = (360 + goVec.y); if (goVec.z > 180) goVec.z = -(360 - goVec.z); if (goVec.z < -180) goVec.z = (360 + goVec.z); //look at this pev->avelocity = goVec * 4; if (pev->fuser3 != 0) { // chase cam on this person // move self to be BEHIND him, iuser1 units away, and fuser3 units above/below //UTIL_MakeVectors( lookVec ); //lookVec = gpGlobals->v_forward * -100; //lookVec.x = 0; //lookVec.z = 0; //lookVec = lookVec * (double)pev->iuser1; double ang = (double)pen->v.v_angle.y; ang -= 180; double newx = (double)pen->v.origin.x + cos(ang * (3.14159 / 180)) * (double)pev->iuser1; double newy = (double)pen->v.origin.y + sin(ang * (3.14159 / 180)) * (double)pev->iuser1; Vector lookVec = pen->v.origin; lookVec.x = newx; lookVec.y = newy; lookVec.z += pev->fuser3; // move here Vector MoveVec = lookVec - pev->origin; pev->velocity = MoveVec; } } } pev->nextthink = gpGlobals->time + 0.1; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CRagdollProp::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ) { BaseClass::VPhysicsCollision( index, pEvent ); CBaseEntity *pHitEntity = pEvent->pEntities[!index]; if ( pHitEntity == this ) return; // Don't take physics damage from whoever's holding him with the physcannon. if ( VPhysicsGetObject() && (VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD) ) { if ( pHitEntity && (pHitEntity == HasPhysicsAttacker( FLT_MAX )) ) return; } // Don't bother taking damage from the physics attacker if ( pHitEntity && HasPhysicsAttacker( 0.5f ) == pHitEntity ) return; if( m_bFirstCollisionAfterLaunch ) { HandleFirstCollisionInteractions( index, pEvent ); } if ( m_takedamage != DAMAGE_NO ) { int damageType = 0; float damage = CalculateDefaultPhysicsDamage( index, pEvent, 1.0f, true, damageType ); if ( damage > 0 ) { // Take extra damage after we're punted by the physcannon if ( m_bFirstCollisionAfterLaunch ) { damage *= 10; } CBaseEntity *pHitEntity = pEvent->pEntities[!index]; if ( !pHitEntity ) { // hit world pHitEntity = GetContainingEntity( INDEXENT(0) ); } Vector damagePos; pEvent->pInternalData->GetContactPoint( damagePos ); Vector damageForce = pEvent->postVelocity[index] * pEvent->pObjects[index]->GetMass(); if ( damageForce == vec3_origin ) { // This can happen if this entity is motion disabled, and can't move. // Use the velocity of the entity that hit us instead. damageForce = pEvent->postVelocity[!index] * pEvent->pObjects[!index]->GetMass(); } // FIXME: this doesn't pass in who is responsible if some other entity "caused" this collision PhysCallbackDamage( this, CTakeDamageInfo( pHitEntity, pHitEntity, damageForce, damagePos, damage, damageType ), *pEvent, index ); } } if ( m_bFirstCollisionAfterLaunch ) { // Setup the think function to remove the flags SetThink( &CRagdollProp::ClearFlagsThink ); SetNextThink( gpGlobals->curtime ); } }
{ iAttribIndices[i] = *(short int*)((unsigned int)pAttribList + (i * 16) + 4); CBotGlobals::botMessage(NULL, 0, "%d) %d", i, iAttribIndices[i]); } return iNumAttribs; } CON_COMMAND(rcbot_printattribs, "print attributes") { if (args.ArgC() > 1) { int slot = atoi(args.Arg(1)); edict_t *pEdict = INDEXENT(1); if (slot >= 0) { CBaseEntity *pEntity = RCBotPluginMeta::TF2_getPlayerWeaponSlot(pEdict, slot); if (pEntity) pEdict = servergameents->BaseEntityToEdict(pEntity); } if (pEdict) UTIL_ListAttributesOnEntity(pEdict); } }
// SyPB Pro P.29 - new Look UP Enemy bool Bot::LookupEnemy(void) { m_visibility = 0; m_enemyOrigin = nullvec; if (m_blindTime > engine->GetTime() || sypb_noshots.GetBool()) return false; if (!FNullEnt(m_lastEnemy)) { if (IsNotAttackLab(m_lastEnemy) || !IsAlive(m_lastEnemy) || (GetTeam(m_lastEnemy) == GetTeam(GetEntity()))) { m_lastEnemy = null; m_lastEnemyOrigin = nullvec; } } if (!FNullEnt(m_lastVictim)) { if (!IsAlive(m_lastVictim) || (GetTeam(m_lastVictim) == GetTeam(GetEntity()))) m_lastVictim = null; } m_states &= ~STATE_SUSPECTENEMY; int team = GetTeam(GetEntity()), i; edict_t *entity = null, *targetEntity = null; float enemy_distance = 9999.0f; // SyPB Pro P.30 - AMXX API if (m_blockCheckEnemyTime > engine->GetTime()) { if (!FNullEnt(m_moveTargetEntityAPI)) { if (GetTeam(GetEntity()) != GetTeam(m_moveTargetEntityAPI) && IsAlive(m_moveTargetEntityAPI)) SetMoveTarget(m_moveTargetEntityAPI); else { // SyPB Pro P.32 - API Fixed SetMoveTarget(null); m_moveTargetEntityAPI = null; } } else if (!FNullEnt(m_enemyAPI)) { if (GetTeam(GetEntity()) != GetTeam(m_enemyAPI) && IsAlive(m_enemyAPI)) { m_targetEntity = null; m_enemy = m_enemyAPI; m_lastEnemy = m_enemy; m_lastEnemyOrigin = GetEntityOrigin(m_enemy); m_enemyReachableTimer = 0.0f; m_seeEnemyTime = engine->GetTime(); if (!IsEnemyViewable(m_enemy, 1)) m_enemyOrigin = GetEntityOrigin(m_enemy); return true; } else m_enemyAPI = null; } return false; } m_enemyAPI = null; m_moveTargetEntityAPI = null; if (!FNullEnt(m_enemy)) { if (GetTeam(GetEntity()) == GetTeam(m_enemy) || IsNotAttackLab(m_enemy) || !IsAlive(m_enemy)) return false; if (m_enemyUpdateTime > engine->GetTime() && !(m_states & STATE_SUSPECTENEMY)) { m_aimFlags |= AIM_ENEMY; return true; } if (IsEnemyViewable(m_enemy, 1)) { targetEntity = m_enemy; enemy_distance = GetEntityDistance(m_enemy); } } else if (!FNullEnt(m_moveTargetEntity)) { if (GetTeam(GetEntity()) == GetTeam(m_moveTargetEntity) || !IsAlive(m_moveTargetEntity)) { SetMoveTarget(null); return false; } targetEntity = m_moveTargetEntity; m_moveTargetOrigin = GetEntityOrigin(m_moveTargetEntity); enemy_distance = GetEntityDistance(m_moveTargetEntity); } // SyPB Pro P.34 - Zombie mode if (IsZombieBot(GetEntity())) { if (!FNullEnt(m_moveTargetEntity)) { if (m_enemyUpdateTime > engine->GetTime()) return false; } if (FNullEnt (m_enemy)) m_enemyUpdateTime = engine->GetTime() + 0.15f; } for (i = 1; i <= engine->GetMaxClients(); i++) { entity = INDEXENT(i); if (FNullEnt(entity) || !IsAlive(entity) || GetTeam(entity) == team || entity == GetEntity()) continue; if (IsBehindSmokeClouds(entity) && m_blindRecognizeTime < engine->GetTime()) m_blindRecognizeTime = engine->GetTime() + engine->RandomFloat(2.0, 3.0f); if (m_blindRecognizeTime >= engine->GetTime()) continue; float distance = GetEntityDistance(entity); if (distance >= enemy_distance) continue; if (IsEnemyProtectedByShield(entity)) continue; if (IsEnemyViewable(entity)) { enemy_distance = distance; targetEntity = entity; if ((g_mapType & MAP_AS) && *(INFOKEY_VALUE(GET_INFOKEYBUFFER(entity), "model")) == 'v') break; } } ITERATE_ARRAY(g_entityName, j) { if (g_entityAction[j] != 1 || (GetTeam(GetEntity()) == (g_entityTeam[j] - 1) && g_entityTeam[j] != 0)) continue; while (!FNullEnt(entity = FIND_ENTITY_BY_CLASSNAME(entity, g_entityName[j]))) { if (FNullEnt(entity) || entity == m_enemy) continue; float distance = GetEntityDistance(entity); if (distance >= enemy_distance) continue; if (IsBehindSmokeClouds(entity) && m_blindRecognizeTime < engine->GetTime()) m_blindRecognizeTime = engine->GetTime() + engine->RandomFloat(2.0, 3.0f); // SyPB Pro P.30 - NPC Fixed if (IsEnemyViewable(entity)) { enemy_distance = distance; targetEntity = entity; } } } if (!FNullEnt(targetEntity)) // Last Checking { enemy_distance = GetEntityDistance(targetEntity); if (GetTeam(targetEntity) == team || !IsEnemyViewable(targetEntity, 1)) targetEntity = null; } if (!FNullEnt(m_enemy) && IsZombieBot(GetEntity())) { if (FNullEnt(targetEntity)) // Has not new enemy, and cannot see old enemy { g_botsCanPause = false; // SyPB Pro P.32 - Zombie Ai int botSrcIndex = g_waypoint->FindNearest(pev->origin); int targetSrcIndex = g_waypoint->FindNearest(GetEntityOrigin (m_enemy)); int botStartIndex = *(g_waypoint->m_pathMatrix + (botSrcIndex * g_numWaypoints) + targetSrcIndex); if (!(botStartIndex < 0)) ChangeWptIndex(botStartIndex); RemoveCertainTask(TASK_MOVETOTARGET); SetMoveTarget(m_enemy); return false; } // SyPB Pro P.30 - Zombie Ai else if (targetEntity != m_enemy) { float distance = GetEntityDistance(m_enemy); if (enemy_distance + 50.0f >= distance) { targetEntity = m_enemy; enemy_distance = distance; } } } if (!FNullEnt(targetEntity)) { // SyPB Pro P.34 - Zombie Ai if (IsZombieBot(GetEntity())) { // SyPB Pro P.36 - Zombie Ai float distance = GetEntityDistance(targetEntity); enemy_distance = (GetEntityOrigin (targetEntity) - pev->origin).GetLength(); bool moveTotarget = false; if (enemy_distance >= 150.0f) { moveTotarget = true; if (targetEntity == m_moveTargetEntity) { if (m_navNode == null || (m_navNode != null && m_navNode->next == null)) { moveTotarget = false; // SyPB Pro P.37 - Zombie Ai m_enemyUpdateTime = engine->GetTime() + 4.0f; } } } else if (enemy_distance >= 80.0f && distance >= (enemy_distance * 2)) moveTotarget = true; //else if (m_navNode != null && enemy_distance > 20.0f && distance >= 30.0f)//&& enemy_distance > 40.0f) else if (m_navNode != null && enemy_distance >= 20.0f)// && distance >= 30.0f) { PathNode *navid = &m_navNode[0]; Path *path; while (navid != null) { path = g_waypoint->GetPath(navid->index); navid = navid->next; if (navid != null) { if (path->connectionFlags[navid->index] & PATHFLAG_JUMP) { moveTotarget = true; navid = null; } } } } if (moveTotarget) { // SyPB Pro P.35 - Fixed if (enemy_distance <= 80.0f) //if (moveTotarget <= 80.0f) pev->button |= IN_ATTACK; if (targetEntity != m_moveTargetEntity) { g_botsCanPause = false; // SyPB Pro P.32 - Zombie Ai int botSrcIndex = g_waypoint->FindNearest(pev->origin); int targetSrcIndex = g_waypoint->FindNearest(GetEntityOrigin (targetEntity)); int botStartIndex = *(g_waypoint->m_pathMatrix + (botSrcIndex * g_numWaypoints) + targetSrcIndex); if (!(botStartIndex < 0)) ChangeWptIndex(botStartIndex); SetMoveTarget(targetEntity); } return false; } // SyPB Pro P.37 - Zombie Ai if (m_enemyUpdateTime < engine->GetTime() + 3.0f) m_enemyUpdateTime = engine->GetTime() + 2.5f; } g_botsCanPause = true; m_aimFlags |= AIM_ENEMY; if (targetEntity == m_enemy) { m_seeEnemyTime = engine->GetTime(); m_actualReactionTime = 0.0f; m_lastEnemy = targetEntity; m_lastEnemyOrigin = GetEntityOrigin(targetEntity); return true; } if (m_seeEnemyTime + 3.0f < engine->GetTime() && (pev->weapons & (1 << WEAPON_C4) || HasHostage() || !FNullEnt(m_targetEntity))) RadioMessage(Radio_EnemySpotted); m_targetEntity = null; if (engine->RandomInt(0, 100) < m_skill) m_enemySurpriseTime = engine->GetTime() + (m_actualReactionTime / 3); else m_enemySurpriseTime = engine->GetTime() + m_actualReactionTime; m_actualReactionTime = 0.0f; m_enemy = targetEntity; m_lastEnemy = m_enemy; m_lastEnemyOrigin = GetEntityOrigin(m_enemy); m_enemyReachableTimer = 0.0f; m_seeEnemyTime = engine->GetTime(); if (!IsZombieBot(GetEntity())) m_enemyUpdateTime = engine->GetTime() + 0.6f; //m_enemyUpdateTime = (IsZombieBot(GetEntity()) ? engine->GetTime() + 2.5f : engine->GetTime() + 0.6f); return true; } if ((m_aimFlags <= AIM_PREDICTENEMY && m_seeEnemyTime + 4.0f < engine->GetTime() && !(m_states & (STATE_SEEINGENEMY | STATE_HEARENEMY)) && FNullEnt(m_lastEnemy) && FNullEnt(m_enemy) && GetCurrentTask()->taskID != TASK_DESTROYBREAKABLE && GetCurrentTask()->taskID != TASK_PLANTBOMB && GetCurrentTask()->taskID != TASK_DEFUSEBOMB) || g_roundEnded) { if (!m_reloadState) m_reloadState = RSTATE_PRIMARY; } if ((UsesSniper() || UsesZoomableRifle()) && m_zoomCheckTime + 1.0f < engine->GetTime()) { if (pev->fov < 90) pev->button |= IN_ATTACK2; else m_zoomCheckTime = 0.0f; } return false; }
// think void cChatEngine::think() { if (fThinkTimer + 1.0 < gpGlobals->time) { // decrease if (Game.iProducedSentences > 1) { Game.iProducedSentences--; } if (sender[0] != '\0') { // SERVER_PRINT("ChatEngine: handling sentence, sent by '"); // SERVER_PRINT(sender); // SERVER_PRINT("' who said:\n"); // SERVER_PRINT(sentence); // SERVER_PRINT(" --\n"); // Run some checks on the 'sender'. We need the edict from that edict_t *pSender = NULL; int i; for (i = 1; i <= gpGlobals->maxClients; i++) { edict_t *pPlayer = INDEXENT(i); if (pPlayer && (!pPlayer->free)) { char name[30], name2[30]; // clear memset(name, 0, sizeof(name)); memset(name2, 0, sizeof(name2)); // copy strcpy(name, STRING(pPlayer->v.netname)); strcpy(name2, sender); if (strcmp(name, name2) == 0) { pSender = pPlayer; break; } } } // Scan the message so we know in what block we should be to reply: char word[20]; memset(word, 0, sizeof(word)); int c = 0; //for (c=0; c < 20; c++) // word[c] = '\0'; c = 0; int wc = 0; int length = strlen(sentence); // When length is not valid, get out. if (length == 0 || length >= 127) { memset(sentence, 0, sizeof(sentence)); memset(sender, 0, sizeof(sender)); // reset timer fThinkTimer = gpGlobals->time; return; } // Define word block scores: int WordBlockScore[MAX_BLOCKS]; // Init, none of the block has a score yet (set to -1) for (int wbs = 0; wbs < MAX_BLOCKS; wbs++) WordBlockScore[wbs] = -1; // chSentence char chSentence[128]; // clear first memset(chSentence, 0, sizeof(chSentence)); // copy sprintf(chSentence, "%s", sentence); // C while (c < length) { // protection matters: if (c > length) break; if (c < 0) break; // End of protection matters // Step: Check character to identify the end of a word. if (sentence[c] == ' ' || sentence[c] == '\n' || sentence[c] == '.' || sentence[c] == '?' || sentence[c] == '!' || c == length) { // Now find the word and add up scors on the proper score blocks. if (c == length) word[wc] = sentence[c]; // not a good word (too small) if (strlen(word) <= 0) { //SERVER_PRINT("This is not a good word!\n"); } else { for (int iB = 0; iB < MAX_BLOCKS; iB++) { if (ReplyBlock[iB].bUsed) { for (int iBw = 0; iBw < 10; iBw++) { // skip any word in the reply block that is not valid if (ReplyBlock[iB].word[iBw][0] == '\0') continue; // not filled in if (strlen(ReplyBlock[iB].word[iBw]) <= 0) continue; // not long enough (a space?) // 03/07/04 // add score to matching word (evy: ignoring case) if (strcmpi(ReplyBlock[iB].word[iBw], word) == 0) WordBlockScore[iB]++; } // all words in this block } // any used block } // for all blocks } // good word // clear out entire word. //for (int cw=0; cw < 20; cw++) // word[cw] = '\0'; memset(word, 0, sizeof(word)); wc = 0; // reset WC position (start writing 'word[WC]' at 0 again) c++; // next position in sentence continue; // go to top again. } // when we end up here, we are still reading a 'non finishing word' character. // we will fill that in word[wc]. Then add up wc and c, until we find a character // that marks the end of a word again. // fill in the word: word[wc] = sentence[c]; // add up. c++; wc++; } // end of loop // now loop through all blocks and find the one with the most score: int iMaxScore = -1; int iTheBlock = -1; // for all blocks for (int rB = 0; rB < MAX_BLOCKS; rB++) { // Any block that has the highest score if (WordBlockScore[rB] > iMaxScore) { iMaxScore = WordBlockScore[rB]; iTheBlock = rB; } } // When we have found pSender edict AND we have a block to reply from // we continue here. if (pSender && iTheBlock > -1) { int iMax = -1; // now choose a sentence to reply with for (int iS = 0; iS < 50; iS++) { // Find max sentences of this reply block if (ReplyBlock[iTheBlock].sentence[iS][0] != '\0') iMax++; } // loop through all bots: for (int i = 1; i <= gpGlobals->maxClients; i++) { edict_t *pPlayer = INDEXENT(i); // skip invalid players and skip self (i.e. this bot) if ((pPlayer) && (!pPlayer->free) && pSender != pPlayer) { // only reply to the living when alive, and otherwise bool bSenderAlive = false; bool bPlayerAlive = false; bSenderAlive = IsAlive(pSender); // CRASH : it sometimes crashes here bPlayerAlive = IsAlive(pPlayer); if (bSenderAlive != bPlayerAlive) continue; cBot *pBotPointer = UTIL_GetBotPointer(pPlayer); if (pBotPointer != NULL) if (RANDOM_LONG(0, 100) < (pBotPointer->ipChatRate + 25)) { // When we have at least 1 sentence... if (iMax > -1) { // choose randomly a reply int the_c = RANDOM_LONG(0, iMax); if (iTheBlock == iLastBlock && the_c == iLastSentence) { // when this is the same, avoid it. Try to change again if (iMax > 0) the_c++; else continue; // do not reply double if (the_c > iMax) the_c = 0; } // the_c is choosen, it is the sentence we reply with. // do a check if its valid: if (ReplyBlock[iTheBlock]. sentence[the_c][0] != '\0') { // chSentence is eventually what the bot will say. char chSentence[128]; char temp[80]; memset(chSentence, 0, sizeof(chSentence)); memset(temp, 0, sizeof(temp)); // get character position char *name_pos = strstr(ReplyBlock[iTheBlock]. sentence[the_c], "%n"); // when name_pos var is found, fill it in. if (name_pos != NULL) { // when name is in this one: int name_offset = name_pos - ReplyBlock[iTheBlock].sentence[the_c]; name_offset--; // copy every character till name_offset int nC; for (nC = 0; nC < name_offset; nC++) { //chSentence[nC] = ReplyBlock[iTheBlock].sentence[the_c][nC]; temp[nC] = ReplyBlock[iTheBlock]. sentence[the_c][nC]; } temp[nC] = ' '; // copy senders name to chSentence strcat(temp, sender); // From here us 'tc' to keep track of chSentence and use // nC to keep reading from ReplyBlock int tc = nC; // Skip %n part in ReplyBlock nC = name_offset + 3; // we just copied a name to chSentence // set our cursor after the name now (name length + 1) tc = strlen(temp); // now finish the sentence // get entire length of ReplyBlock and go until we reach the end int length = strlen(ReplyBlock[iTheBlock]. sentence[the_c]); // for every nC , read character from ReplyBlock for (; nC <= length; nC++) { // ... and copy it into chSentence temp[tc] = ReplyBlock[iTheBlock]. sentence[the_c][nC]; //char tmsg[80]; //sprintf(tmsg,"Copying char %c , tc = %d, nC = %d\n", temp[tc], tc, nC); //SERVER_PRINT(tmsg); tc++; // add up tc. } // terminate temp[tc] = '\n'; sprintf(chSentence, "%s \n", temp); } // when no name pos is found, we just copy the string and say that (works ok) else sprintf(chSentence, "%s \n", ReplyBlock[iTheBlock]. sentence[the_c]); // reply: pBotPointer->PrepareChat(chSentence); //UTIL_SayTextBot(chSentence, pBotPointer); // update iLastSentence = the_c; iLastBlock = iTheBlock; } } } } } } // clear sentence and such memset(sentence, 0, sizeof(sentence)); memset(sender, 0, sizeof(sender)); } fThinkTimer = gpGlobals->time + RANDOM_FLOAT(0.0, 0.5); } }
void NPC::FindEnemy(void) { if (m_findEnemyMode == -1) { SetEnemy(null); SetMoveTarget(null); return; } int team = GetTeam(GetEntity()); if (m_enemyAPI != null && (FNullEnt(m_enemyAPI) || !IsAlive(m_enemyAPI) || GetTeam(m_enemyAPI) == team)) m_enemyAPI = null; if (!FNullEnt(m_enemy)) { if (!IsAlive(m_enemy) || GetTeam(m_enemy) == team) { SetEnemy(null); LoadEntityWaypointPoint(GetEntity()); m_currentWaypointIndex = -1; FindWaypoint(); } } if (!FNullEnt(m_moveTargetEntity)) { if (!IsAlive(m_moveTargetEntity) || GetTeam(m_moveTargetEntity) == team) SetMoveTarget(null); } edict_t *targetEntity = null; float enemy_distance = 9999.9f; if (!FNullEnt(m_enemy)) targetEntity = m_enemy; else if (!FNullEnt(m_moveTargetEntity)) targetEntity = m_moveTargetEntity; if (!FNullEnt(targetEntity)) { if (m_enemyUpdateTime > gpGlobals->time) return; enemy_distance = GetEntityDistance(targetEntity); } int i, allEnemy = 0; edict_t *entity = null; if (FNullEnt(m_enemyAPI)) { for (i = 0; i < checkEnemyNum; i++) { m_allEnemyId[i] = -1; m_allEnemyDistance[i] = 9999.9f; m_enemyEntityId[i] = -1; m_enemyEntityDistance[i] = 9999.9f; } for (i = 0; i < gpGlobals->maxClients; i++) { entity = INDEXENT(i + 1); if (FNullEnt(entity) || !IsAlive(entity) || GetTeam(entity) == team) continue; m_allEnemyId[allEnemy] = i + 1; m_allEnemyDistance[allEnemy] = GetEntityDistance(entity); allEnemy++; } for (i = 0; i < MAX_NPC; i++) { NPC *npc = g_npcManager->IsSwNPCForNum(i); if (npc == null) continue; entity = npc->GetEntity(); if (FNullEnt(entity) || !IsAlive(entity) || GetTeam(entity) == team) continue; if (entity->v.effects & EF_NODRAW || entity->v.takedamage == DAMAGE_NO) continue; m_allEnemyId[allEnemy] = npc->GetIndex(); m_allEnemyDistance[allEnemy] = GetEntityDistance(entity); allEnemy++; } for (i = 0; i < allEnemy; i++) { for (int y = 0; y < checkEnemyNum; y++) { if (m_allEnemyDistance[i] >= m_enemyEntityDistance[y]) continue; for (int z = allEnemy - 1; z >= y; z--) { if (z == allEnemy - 1 || m_enemyEntityId[z] == -1) continue; m_enemyEntityId[z + 1] = m_enemyEntityId[z]; m_enemyEntityDistance[z + 1] = m_enemyEntityDistance[z]; } m_enemyEntityId[y] = m_allEnemyId[i]; m_enemyEntityDistance[y] = m_allEnemyDistance[i]; break; } } for (i = 0; i < checkEnemyNum; i++) { if (m_enemyEntityId[i] == -1) continue; entity = INDEXENT(m_enemyEntityId[i]); if (IsEnemyViewable(entity)) { enemy_distance = m_enemyEntityDistance[i]; targetEntity = entity; break; } } } else { targetEntity = m_enemyAPI; enemy_distance = GetEntityDistance(m_enemyAPI); } if (!FNullEnt(m_moveTargetEntity) && m_moveTargetEntity != targetEntity) { if (m_currentWaypointIndex != g_waypoint->GetEntityWpIndex(targetEntity)) { float distance = GetEntityDistance(m_moveTargetEntity); if (distance <= enemy_distance + 400.0f) { enemy_distance = distance; targetEntity = null; } } } if (!FNullEnt(targetEntity)) { if (!IsEnemyViewable(targetEntity)) { if (targetEntity == m_enemyAPI) { SetMoveTarget(targetEntity); return; } targetEntity = null; } } if (!FNullEnt(m_enemy) && FNullEnt (targetEntity)) { SetMoveTarget(m_enemy); return; } if (!FNullEnt(targetEntity)) { if (m_attackDistance <= 300.0f) { bool moveTarget = true; int srcIndex = g_waypoint->GetEntityWpIndex(GetEntity()); int destIndex = g_waypoint->GetEntityWpIndex(targetEntity); enemy_distance = GetDistance(pev->origin, GetEntityOrigin (targetEntity)); if (srcIndex == destIndex || m_currentWaypointIndex == destIndex) moveTarget = false; else if (enemy_distance <= m_attackDistance) moveTarget = false; else if (m_attackDistance <= 120.0f) { if (targetEntity == m_moveTargetEntity && &m_navNode[0] != null) { if (m_navNode->index == destIndex) moveTarget = false; } else { int movePoint = 0; while (srcIndex != destIndex && movePoint < 99 && srcIndex >= 0 && destIndex >= 0) { srcIndex = *(g_waypoint->m_pathMatrix + (srcIndex * g_numWaypoints) + destIndex); if (srcIndex < 0) continue; movePoint++; } if ((enemy_distance <= 120.0f && movePoint <= 2) || (targetEntity == m_moveTargetEntity && movePoint <= 1)) moveTarget = false; } } if (!moveTarget) { SetEnemy(targetEntity); return; } SetMoveTarget(targetEntity); } else SetEnemy(targetEntity); } }
// GAME: Update global vars (called by StartFrame) void cGame::UpdateGameStatus() { // Used variables edict_t *pEnt; pEnt = NULL; // ------------------ // Update: Dropped C4 // ------------------ // Its not dropped unless stated otherwise. vDroppedC4 = Vector(9999, 9999, 9999); // Find the dropped bomb while ((pEnt = UTIL_FindEntityByClassname(pEnt, "weaponbox")) != NULL) { // when DROPPED C4 if ((FStrEq(STRING(pEnt->v.model), "models/w_backpack.mdl"))) { vDroppedC4 = pEnt->v.origin; // this is the origin. break; } } // ------------------ // Update: Is the bomb planted? // ------------------ // Same as dropped c4, its NOT, unless stated otherwise. pEnt = NULL; Vector vVec = Vector(9999, 9999, 9999); bool bPlanted = bBombPlanted; // is it planted? while ((pEnt = UTIL_FindEntityByClassname(pEnt, "grenade")) != NULL) { if (UTIL_GetGrenadeType(pEnt) == 4) { // Found planted bomb: bPlanted = true; float fDist = 200; int iBot = -1, k = 1; vVec = pEnt->v.origin; // FIND: // Find the player near this bomb for (; k <= gpGlobals->maxClients; k++) { edict_t *pPlayer = INDEXENT(k); // skip invalid players if ((pPlayer) && (!pPlayer->free)) { // skip this player if not alive (i.e. dead or dying) if (!IsAlive(pPlayer)) continue; if (!(pPlayer->v.flags & FL_THIRDPARTYBOT)) continue; // skip real players (or NOT realbot's) if (UTIL_GetBotPointer(pPlayer) == NULL) continue; // Check the distance if (func_distance(vVec, pPlayer->v.origin) < fDist) { iBot = k; // remember this ID fDist = func_distance(vVec, pPlayer->v.origin); // update distance } } } // End of search // all counter-terrorists should know this, and they should head for the bomb if (bPlanted && bPlanted != bBombPlanted) { int i; for (i = 1; i <= gpGlobals->maxClients; i++) { edict_t *pPlayer = INDEXENT(i); cBot *bot = UTIL_GetBotPointer(pPlayer); if (bot) // valid bot { if (UTIL_GetTeam(bot->pEdict) == 1) // Counter-Terrorists { bot->bot_pathid = -1; bot->iGoalNode = NodeMachine.node_goal(GOAL_BOMBSPOT); } // ct } // bot } // through all clients // It is not yet discovered bBombDiscovered = false; // Now update bBombPlanted bBombPlanted = bPlanted; } // planted, and not planted before } } // When bPlanted = false, we set bBombPlanted to false if (bPlanted == false) { bBombPlanted = false; } } // UpdateGameStatus()
void CTFObjectiveResource::setup () { CClassInterface::getTF2ObjectiveResource(this); memset(m_pControlPoints,0,sizeof(edict_t*)*MAX_CONTROL_POINTS); memset(m_iControlPointWpt,0xFF,sizeof(int)*MAX_CONTROL_POINTS); memset(m_fLastCaptureTime,0,sizeof(float)*MAX_CONTROL_POINTS); // Find control point entities edict_t *pent; Vector vOrigin; int i = gpGlobals->maxClients; memset(m_IndexToWaypointAreaTranslation,0,sizeof(int)*MAX_CONTROL_POINTS); memset(m_WaypointAreaToIndexTranslation,0xFF,sizeof(int)*(MAX_CONTROL_POINTS+1)); // find visible flags -- with a model while ( ++i < gpGlobals->maxEntities ) { pent = INDEXENT(i); if ( !pent || pent->IsFree() ) continue; if ( strcmp(pent->GetClassName(),"team_control_point") == 0 ) { vOrigin = CBotGlobals::entityOrigin(pent); for ( int j = 0; j < *m_iNumControlPoints; j ++ ) { if ( m_pControlPoints[j].get() != NULL ) continue; if ( vOrigin == m_vCPPositions[j] ) { m_pControlPoints[j] = MyEHandle(pent); //m_pControlPointClass[j] = CTeamControlPoint::getPoint(pent); } } } } CWaypoint *pWaypoint; int iWpt; for ( int j = 0; j < *m_iNumControlPoints; j ++ ) { vOrigin = m_vCPPositions[j]; if ( m_iControlPointWpt[j] == -1 ) { iWpt = CWaypointLocations::NearestWaypoint(vOrigin,1024.0f,-1,false,false,false,NULL,false,0,false,false,Vector(0,0,0),CWaypointTypes::W_FL_CAPPOINT); pWaypoint = CWaypoints::getWaypoint(iWpt); m_iControlPointWpt[j] = iWpt; // For compatibility -- old waypoints are already set with an area, so take the area from the waypoint here // in the future waypoints will automatically be set to the waypoint area anyway if ( pWaypoint ) { int iArea = pWaypoint->getArea(); m_IndexToWaypointAreaTranslation[j] = iArea; if ( ( iArea >= 1 ) && ( iArea < MAX_CONTROL_POINTS ) ) m_WaypointAreaToIndexTranslation[iArea] = j; } else { m_IndexToWaypointAreaTranslation[j] = 0; m_WaypointAreaToIndexTranslation[j+1] = -1; } } } m_bInitialised = true; }
void CFlagEvent::Execute(IBotEventInterface *pEvent) { // dropped / picked up ID int type = pEvent->GetInt("eventtype"); // player id int player = pEvent->GetInt("player"); edict_t *pPlayer = NULL; CBot *pBot = NULL; // Crash fix if (player) { pPlayer = INDEXENT(player); pBot = CBots::GetBotPointer(pPlayer); } switch (type) { case FLAG_PICKUP: // pickup if (pBot && pBot->IsTF()) { ((CBotTF2*)pBot)->PickedUpFlag(); } if (pPlayer) { int iTeam = CTeamFortress2Mod::GetTeam(pPlayer); if (CTeamFortress2Mod::IsFlagAtDefaultState()) { CClient *pClient; pClient = CClients::Get(pPlayer); if (pClient && pClient->AutoWaypointOn()) pClient->AutoEventWaypoint(CWaypointTypes::W_FL_FLAG, 200.0f, false); } CTeamFortress2Mod::FlagPickedUp(iTeam, pPlayer); } break; case FLAG_CAPTURED: // captured { IPlayerInfo *p = NULL; if (pPlayer) { p = playerinfomanager->GetPlayerInfo(pPlayer); if (p) { CBroadcastFlagCaptured captured = CBroadcastFlagCaptured(p->GetTeamIndex()); CBots::BotFunction(&captured); } } if (pBot && pBot->IsTF()) { ((CBotTF2*)pBot)->CapturedFlag(); ((CBotTF2*)pBot)->DroppedFlag(); } if (pPlayer) { int iTeam = CTeamFortress2Mod::GetTeam(pPlayer); CTeamFortress2Mod::FlagDropped(iTeam, Vector(0, 0, 0)); CClient *pClient; pClient = CClients::Get(pPlayer); if (pClient && pClient->AutoWaypointOn()) pClient->AutoEventWaypoint(CWaypointTypes::W_FL_CAPPOINT, 200.0f, false); } CTeamFortress2Mod::ResetFlagStateToDefault(); } break; case FLAG_DROPPED: // drop { IPlayerInfo *p = playerinfomanager->GetPlayerInfo(pPlayer); Vector vLoc; if (p) { vLoc = CBotGlobals::EntityOrigin(pPlayer); CBroadcastFlagDropped dropped = CBroadcastFlagDropped(p->GetTeamIndex(), vLoc); CBots::BotFunction(&dropped); } if (pBot && pBot->IsTF()) ((CBotTF2*)pBot)->DroppedFlag(); if (pPlayer) CTeamFortress2Mod::FlagDropped(CTeamFortress2Mod::GetTeam(pPlayer), vLoc); } break; case FLAG_RETURN: { if (CTeamFortress2Mod::IsMapType(TF_MAP_SD)) { CBroadcastFlagReturned returned = CBroadcastFlagReturned(CTeamFortress2Mod::GetFlagCarrierTeam()); CBots::BotFunction(&returned); } CTeamFortress2Mod::ResetFlagStateToDefault(); CTeamFortress2Mod::FlagReturned(0); // for special delivery //p->GetTeamIndex(),CBotGlobals::EntityOrigin(pPlayer)); } break; default: break; } }
CBaseEntity* CHL2MP_Player::EntSelectSpawnPoint( void ) { CBaseEntity *pSpot = NULL; CBaseEntity *pLastSpawnPoint = g_pLastSpawn; edict_t *player = edict(); const char *pSpawnpointName = "info_player_deathmatch"; if ( HL2MPRules()->IsTeamplay() == true ) { if ( GetTeamNumber() == TEAM_COMBINE ) { pSpawnpointName = "info_player_combine"; pLastSpawnPoint = g_pLastCombineSpawn; } else if ( GetTeamNumber() == TEAM_REBELS ) { pSpawnpointName = "info_player_rebel"; pLastSpawnPoint = g_pLastRebelSpawn; } if ( gEntList.FindEntityByClassname( NULL, pSpawnpointName ) == NULL ) { pSpawnpointName = "info_player_deathmatch"; pLastSpawnPoint = g_pLastSpawn; } } pSpot = pLastSpawnPoint; // Randomize the start spot for ( int i = random->RandomInt(1,5); i > 0; i-- ) pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); if ( !pSpot ) // skip over the null point pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); CBaseEntity *pFirstSpot = pSpot; do { if ( pSpot ) { // check if pSpot is valid if ( g_pGameRules->IsSpawnPointValid( pSpot, this ) ) { if ( pSpot->GetLocalOrigin() == vec3_origin ) { pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); continue; } // if so, go to pSpot goto ReturnSpot; } } // increment pSpot pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); } while ( pSpot != pFirstSpot ); // loop if we're not back to the start // we haven't found a place to spawn yet, so kill any guy at the first spawn point and spawn there if ( pSpot ) { CBaseEntity *ent = NULL; for ( CEntitySphereQuery sphere( pSpot->GetAbsOrigin(), 128 ); (ent = sphere.GetCurrentEntity()) != NULL; sphere.NextEntity() ) { // if ent is a client, kill em (unless they are ourselves) if ( ent->IsPlayer() && !(ent->edict() == player) ) ent->TakeDamage( CTakeDamageInfo( GetContainingEntity(INDEXENT(0)), GetContainingEntity(INDEXENT(0)), 300, DMG_GENERIC ) ); } goto ReturnSpot; } if ( !pSpot ) { pSpot = gEntList.FindEntityByClassname( pSpot, "info_player_start" ); if ( pSpot ) goto ReturnSpot; } ReturnSpot: if ( HL2MPRules()->IsTeamplay() == true ) { if ( GetTeamNumber() == TEAM_COMBINE ) { g_pLastCombineSpawn = pSpot; } else if ( GetTeamNumber() == TEAM_REBELS ) { g_pLastRebelSpawn = pSpot; } } g_pLastSpawn = pSpot; m_flSlamProtectTime = gpGlobals->curtime + 0.5; return pSpot; }
void OnPluginsLoaded(void) { NEW_Initialize(INDEXENT(0)); }
void RadioHandleMenuItem(edict_t *pEntity, const char *itm) { int ind = ENTINDEX(pEntity); if (!pEntity) return; // Cant use camera in spec mode if (pEntity->v.iuser1 > 0) return; // Are we even supposed to hangle this? if (menushow2[ind] != 0 && (gpGlobals->time <= menushow2[ind])) { menushow2[ind] = 0; edict_t *pentUsed = INDEXENT(lastMenuEnt[ind]); if (FNullEnt(pentUsed)) return; // dont use if radio is tuning if (pentUsed->v.iuser1 == 1) return; // See what they pressed. // menu page 1 if (lastMenuPage[ind] == 1 || lastMenuPage[ind] == 2) { if (lastMenuPage[ind] == 1) { if (FStrEq(itm, "1")) { RadioSwitchToSong(1, lastMenuEnt[ind]); } else if (FStrEq(itm, "2")) { RadioSwitchToSong(2, lastMenuEnt[ind]); } else if (FStrEq(itm, "3")) { RadioSwitchToSong(3, lastMenuEnt[ind]); } else if (FStrEq(itm, "4")) { RadioSwitchToSong(4, lastMenuEnt[ind]); } else if (FStrEq(itm, "5")) { RadioSwitchToSong(5, lastMenuEnt[ind]); } else if (FStrEq(itm, "6")) { RadioShowMenu( pEntity, pentUsed, 2 ); } } else if (lastMenuPage[ind] == 2) { // menu page 2 if (FStrEq(itm, "1")) { RadioSwitchToSong(6, lastMenuEnt[ind]); } else if (FStrEq(itm, "2")) { RadioSwitchToSong(7, lastMenuEnt[ind]); } else if (FStrEq(itm, "3")) { RadioSwitchToSong(8, lastMenuEnt[ind]); } else if (FStrEq(itm, "4")) { RadioSwitchToSong(9, lastMenuEnt[ind]); } else if (FStrEq(itm, "5")) { RadioSwitchToSong(10, lastMenuEnt[ind]); } else if (FStrEq(itm, "6")) { RadioShowMenu( pEntity, pentUsed, 1 ); } } if (FStrEq(itm, "7")) { RadioSwitchToSong(100, lastMenuEnt[ind]); } else if (FStrEq(itm, "8")) { RadioSwitchToSong(101, lastMenuEnt[ind]); } else if (FStrEq(itm, "9")) { RadioShowMenu( pEntity, pentUsed, 3 ); } } else if (lastMenuPage[ind] == 3) { if (FStrEq(itm, "1")) { RadioChangeSongPitch(100, pentUsed); } else if (FStrEq(itm, "2")) { RadioChangeSongPitch(50, pentUsed); } else if (FStrEq(itm, "3")) { RadioChangeSongPitch(80, pentUsed); } else if (FStrEq(itm, "4")) { RadioChangeSongPitch(120, pentUsed); } else if (FStrEq(itm, "5")) { RadioChangeSongPitch(140, pentUsed); } else if (FStrEq(itm, "6")) { RadioChangeSongPitch(150, pentUsed); } else if (FStrEq(itm, "7")) { RadioChangeSongPitch(180, pentUsed); } else if (FStrEq(itm, "8")) { RadioChangeSongPitch(200, pentUsed); } else if (FStrEq(itm, "9")) { RadioShowMenu( pEntity, pentUsed, 1 ); } } } }
void BotClient_CS_SayText(void *p, int bot_index) { static unsigned char ucEntIndex; static int state = 0; // current state machine state // Different Counter-Strike versions mean different // handling of this "SayText" thingy. if (counterstrike == 0) { if (state == 0) { ucEntIndex = *(unsigned char *) p; } else if (state == 1) { cBot *pBot = &bots[bot_index]; if (ENTINDEX(pBot->pEdict) != ucEntIndex) { char sentence[128]; char chSentence[128]; char netname[30]; memset(sentence, 0, sizeof(sentence)); memset(chSentence, 0, sizeof(chSentence)); memset(netname, 0, sizeof(netname)); strcpy(sentence, (char *) p); int length = 0; // FIXED: In any case that this might return NULL, do not crash the server if (strstr(sentence, " : ")) length = strlen(sentence) - strlen(strstr(sentence, " : ")); int tc = 0, c; for (c = length; c < 128; c++) { chSentence[tc] = sentence[c]; tc++; } /* int nc=0; c=2; if (strstr(sentence, "*DEAD*")) c+=6; if (counterstrike == 0) c=1; for (c; c < length; c++) { netname[nc] = sentence[c]; nc++; } */ edict_t *pPlayer = INDEXENT(ucEntIndex); strcpy(netname, STRING(pPlayer->v.netname)); ChatEngine.set_sentence(netname, chSentence); state = -1; } } } else if (counterstrike == 1) { // CS 1.6 if (state == 0) { // who sent this message? ucEntIndex = *(unsigned char *) p; } // to who? else if (state == 1) { // here must be some team check so we do not let bots // of the other team react to this somehow.. // - after playing with the dll i did not notice any weird stuff yet... // - so only when people discover some bugs with this we are going to fix this // - thing... ie "Only fix it when its broken". } // don't know? else if (state == 2) { // do nothing here } // the actual sentence else if (state == 3) { // sentence char sentence[128]; char netname[30]; // init memset(sentence, 0, sizeof(sentence)); memset(netname, 0, sizeof(netname)); // copy in memory strcpy(sentence, (char *) p); // copy netname edict_t *pPlayer = INDEXENT(ucEntIndex); strcpy(netname, STRING(pPlayer->v.netname)); // and give chatengine something to do ChatEngine.set_sentence(netname, sentence); state = -1; } } state++; }
/* <36b780> ../cstrike/dlls/bot/cs_bot_manager.cpp:1109 */ void CCSBotManager::ValidateMapData(void) { if (IMPLEMENT_ARRAY(m_isMapDataLoaded) || !UTIL_IsGame("czero")) { return; } IMPLEMENT_ARRAY(m_isMapDataLoaded) = true; // TODO: Reverse me if (LoadNavigationMap()) { CONSOLE_ECHO("Failed to load navigation map.\n"); return; } CONSOLE_ECHO("Navigation map loaded.\n"); m_zoneCount = 0; m_gameScenario = SCENARIO_DEATHMATCH; // Search all entities in the map and set the game type and // store all zones (bomb target, etc). CBaseEntity *entity = NULL; int i; for (i = 1; i < gpGlobals->maxEntities; i++) { entity = CBaseEntity::Instance(INDEXENT(i)); if (entity == NULL) continue; bool found = false; bool isLegacy = false; if (FClassnameIs(entity->pev, "func_bomb_target")) { found = true; isLegacy = false; m_gameScenario = SCENARIO_DEFUSE_BOMB; } else if (FClassnameIs(entity->pev, "info_bomb_target")) { found = true; isLegacy = true; m_gameScenario = SCENARIO_DEFUSE_BOMB; } else if (FClassnameIs(entity->pev, "func_hostage_rescue")) { found = true; isLegacy = false; m_gameScenario = SCENARIO_RESCUE_HOSTAGES; } else if (FClassnameIs(entity->pev, "info_hostage_rescue")) { found = true; isLegacy = true; m_gameScenario = SCENARIO_RESCUE_HOSTAGES; } else if (FClassnameIs(entity->pev, "hostage_entity")) { // some very old maps (ie: cs_assault) use info_player_start // as rescue zones, so set the scenario if there are hostages // in the map m_gameScenario = SCENARIO_RESCUE_HOSTAGES; } else if (FClassnameIs(entity->pev, "func_vip_safetyzone")) { found = true; isLegacy = false; m_gameScenario = SCENARIO_ESCORT_VIP; } if (found) { if (m_zoneCount < MAX_ZONES) { if (isLegacy) m_zone[ m_zoneCount ].m_center = entity->pev->origin; else m_zone[ m_zoneCount ].m_center = (entity->pev->absmax + entity->pev->absmin) / 2.0f; m_zone[ m_zoneCount ].m_isLegacy = isLegacy; m_zone[ m_zoneCount ].m_index = m_zoneCount; m_zone[ m_zoneCount ].m_entity = entity; ++m_zoneCount; } else CONSOLE_ECHO("Warning: Too many zones, some will be ignored.\n"); } } // If there are no zones and the scenario is hostage rescue, // use the info_player_start entities as rescue zones. if (m_zoneCount == 0 && m_gameScenario == SCENARIO_RESCUE_HOSTAGES) { entity = NULL; while ((entity = UTIL_FindEntityByClassname(entity, "info_player_start")) != NULL) { if (FNullEnt(entity->edict())) break; if (m_zoneCount < MAX_ZONES) { m_zone[ m_zoneCount ].m_center = entity->pev->origin; m_zone[ m_zoneCount ].m_isLegacy = true; m_zone[ m_zoneCount ].m_index = m_zoneCount; m_zone[ m_zoneCount ].m_entity = entity; ++m_zoneCount; } else CONSOLE_ECHO("Warning: Too many zones, some will be ignored.\n"); } } // Collect nav areas that overlap each zone for (i = 0; i < m_zoneCount; i++) { Zone *zone = &m_zone[i]; if (zone->m_isLegacy) { const float legacyRange = 256.0f; zone->m_extent.lo.x = zone->m_center.x - legacyRange; zone->m_extent.lo.y = zone->m_center.y - legacyRange; zone->m_extent.lo.z = zone->m_center.z - legacyRange; zone->m_extent.hi.x = zone->m_center.x + legacyRange; zone->m_extent.hi.y = zone->m_center.y + legacyRange; zone->m_extent.hi.z = zone->m_center.z + legacyRange; } else { zone->m_extent.lo = zone->m_entity->pev->absmin; zone->m_extent.hi = zone->m_entity->pev->absmax; } // ensure Z overlap const float zFudge = 50.0f; zone->m_areaCount = 0; zone->m_extent.lo.z -= zFudge; zone->m_extent.hi.z += zFudge; // build a list of nav areas that overlap this zone for (NavAreaList::iterator iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter) { CNavArea *area = (*iter); const Extent *areaExtent = area->GetExtent(); if (areaExtent->hi.x >= zone->m_extent.lo.x && areaExtent->lo.x <= zone->m_extent.hi.x && areaExtent->hi.y >= zone->m_extent.lo.y && areaExtent->lo.y <= zone->m_extent.hi.y && areaExtent->hi.z >= zone->m_extent.lo.z && areaExtent->lo.z <= zone->m_extent.hi.z) { // area overlaps zone zone->m_area[ zone->m_areaCount++ ] = area; if (zone->m_areaCount == MAX_ZONE_NAV_AREAS) { break; } } } } }
bool CBotWeapons::Update(bool bOverrideAllFromEngine) { // create mask of weapons data short int i = 0; unsigned short int iWeaponsSignature = 0x0; // check sum of weapons edict_t *pWeapon; CBaseHandle *m_Weapons = CClassInterface::GetWeaponList(m_pBot->GetEdict()); CBaseHandle *m_Weapon_iter; m_Weapon_iter = m_Weapons; for (i = 0; i < MAX_WEAPONS; i++) { // create a 'hash' of current weapons pWeapon = (m_Weapon_iter == NULL) ? NULL : INDEXENT(m_Weapon_iter->GetEntryIndex()); iWeaponsSignature += ((unsigned int)pWeapon) + ((pWeapon == NULL) ? 0 : (unsigned int)CClassInterface::GetWeaponState(pWeapon)); m_Weapon_iter++; } // if weapons have changed this will be different if (iWeaponsSignature != m_iWeaponsSignature) // m_fUpdateWeaponsTime < engine->Time() ) { this->ClearWeapons(); int iWeaponState; register unsigned short int i; bool bFound; const char *pszClassname; CBaseHandle *m_Weapons = CClassInterface::GetWeaponList(m_pBot->GetEdict()); CBotWeapon *m_BotWeapon_iter = m_theWeapons; // loop through the weapons array and see if it is in the CBaseCombatCharacter for (i = 0; i < MAX_WEAPONS; i++) { m_Weapon_iter = &m_Weapons[i]; iWeaponState = 0; bFound = false; pWeapon = INDEXENT(m_Weapon_iter->GetEntryIndex()); if (!pWeapon || pWeapon->IsFree()) { continue; } iWeaponState = CClassInterface::GetWeaponState(pWeapon); pszClassname = pWeapon->GetClassName(); CWeapon *pWeaponInfo = CWeapons::GetWeapon(pszClassname); if (pWeaponInfo != NULL) { if (iWeaponState != WEAPON_NOT_CARRIED) { CBotWeapon *pAdded = AddWeapon(pWeaponInfo, i, pWeapon, bOverrideAllFromEngine); pAdded->SetHasWeapon(true); } } } // check again in 1 second m_fUpdateWeaponsTime = engine->Time() + 1.0f; m_iWeaponsSignature = iWeaponsSignature; return true; // change } return false; }
static cell AMX_NATIVE_CALL set_tr2(AMX *amx, cell *params) { TraceResult *tr; if (params[1] == 0) tr = &g_tr_2; else tr = reinterpret_cast<TraceResult *>(params[1]); if (*params / sizeof(cell) < 3) { MF_LogError(amx, AMX_ERR_NATIVE, "No data passed"); return 0; } cell *ptr = MF_GetAmxAddr(amx, params[3]); switch (params[2]) { case TR_AllSolid: { tr->fAllSolid = *ptr; return 1; break; } case TR_InOpen: { tr->fInOpen = *ptr; return 1; break; } case TR_StartSolid: { tr->fStartSolid = *ptr; return 1; break; } case TR_InWater: { tr->fInWater = *ptr; return 1; break; } case TR_flFraction: { tr->flFraction = amx_ctof(*ptr); return 1; break; } case TR_vecEndPos: { tr->vecEndPos.x = amx_ctof(ptr[0]); tr->vecEndPos.y = amx_ctof(ptr[1]); tr->vecEndPos.z = amx_ctof(ptr[2]); return 1; break; } case TR_flPlaneDist: { tr->flPlaneDist = amx_ctof(*ptr); return 1; break; } case TR_vecPlaneNormal: { tr->vecPlaneNormal.x = amx_ctof(ptr[0]); tr->vecPlaneNormal.y = amx_ctof(ptr[1]); tr->vecPlaneNormal.z = amx_ctof(ptr[2]); return 1; break; } case TR_pHit: { edict_t *e = INDEXENT(*ptr); if (!e || FNullEnt(e)) return 0; //TODO: return error tr->pHit = e; return 1; break; } case TR_iHitgroup: { tr->iHitgroup = *ptr; return 1; break; } default: { MF_LogError(amx, AMX_ERR_NATIVE, "Unknown TraceResult member %d", params[2]); return 0; } } return 0; }
void CBotVisibles::UpdateVisibles() { static bool bVisible; static edict_t *pEntity; static edict_t *pGroundEntity; extern ConVar bot_supermode; static int iTicks; static int iMaxTicks; //m_pBot->getProfile()->getVisionTicks(); static int iStartIndex; static int iMaxClientTicks; static int iStartPlayerIndex; static int iSpecialIndex; //update ground entity pGroundEntity = CClassInterface::GetGroundEntity(m_pBot->GetEdict()); if (pGroundEntity && (ENTINDEX(pGroundEntity) > 0)) { SetVisible(pGroundEntity, true); m_pBot->SetVisible(pGroundEntity, true); } iTicks = 0; if (bot_supermode.GetBool()) iMaxTicks = 100; else iMaxTicks = m_pBot->GetProfile()->m_iVisionTicks;// bot_visrevs.GetInt(); iStartIndex = m_iCurrentIndex; if (bot_supermode.GetBool()) iMaxClientTicks = (MAX_PLAYERS / 2) + 1; else iMaxClientTicks = m_pBot->GetProfile()->m_iVisionTicksClients; // bot_visrevs_clients.GetInt(); if (iMaxTicks <= 2) iMaxTicks = 2; if (iMaxClientTicks < 1) iMaxClientTicks = 1; #ifdef _DEBUG CProfileTimer *timer = CProfileTimers::getTimer(BOT_VISION_TIMER); if ( CClients::clientsDebugging(BOT_DEBUG_PROFILE) ) { timer->Start(); } #endif iStartPlayerIndex = m_iCurPlayer; if (m_pBot->MoveToIsValid()) { Vector vMoveTo = m_pBot->GetMoveTo(); if (m_pBot->FVisible(vMoveTo)) m_pBot->UpdateCondition(CONDITION_SEE_WAYPOINT); else m_pBot->RemoveCondition(CONDITION_SEE_WAYPOINT); } // we'll start searching some players first for quick player checking while (iTicks < iMaxClientTicks) { pEntity = INDEXENT(m_iCurPlayer); if (pEntity != pGroundEntity) { if (CBotGlobals::EntityIsValid(pEntity) && (pEntity != m_pBot->GetEdict())) { CheckVisible(pEntity, &iTicks, &bVisible, m_iCurPlayer); SetVisible(pEntity, bVisible); m_pBot->SetVisible(pEntity, bVisible); } } m_iCurPlayer++; if (m_iCurPlayer > CBotGlobals::MaxClients()) m_iCurPlayer = 1; if (iStartPlayerIndex == m_iCurPlayer) break; } if (iMaxTicks > m_iMaxIndex) iMaxTicks = m_iMaxIndex; if (m_iCurPlayer >= m_iCurrentIndex) return; // get entities belonging to players too // we've captured them elsewhere in another data structure which is quicker to find pEntity = m_pBot->GetVisibleSpecial(); iSpecialIndex = 0; if (pEntity) { if (CBotGlobals::EntityIsValid(pEntity)) { iSpecialIndex = ENTINDEX(pEntity); CheckVisible(pEntity, &iTicks, &bVisible, iSpecialIndex, true); SetVisible(pEntity, bVisible); m_pBot->SetVisible(pEntity, bVisible); } } while (iTicks < iMaxTicks) { bVisible = false; pEntity = INDEXENT(m_iCurrentIndex); if ((pEntity != pGroundEntity) && (m_iCurrentIndex != iSpecialIndex)) { if (CBotGlobals::EntityIsValid(pEntity)) { CheckVisible(pEntity, &iTicks, &bVisible, m_iCurrentIndex); SetVisible(pEntity, bVisible); m_pBot->SetVisible(pEntity, bVisible); } } m_iCurrentIndex++; if (m_iCurrentIndex >= m_iMaxIndex) m_iCurrentIndex = CBotGlobals::MaxClients() + 1; // back to start of non clients if (m_iCurrentIndex == iStartIndex) break; // back to where we started } #ifdef _DEBUG if ( CClients::clientsDebugging(BOT_DEBUG_PROFILE) ) { timer->Stop(); } #endif }