void AllyID (edict_t *ent) { vec3_t forward, right, offset, start, end; trace_t tr; edict_t *e=NULL; if (!allies->value) return; if (!numAllies(ent)) return; // find entity near crosshair AngleVectors (ent->client->v_angle, forward, right, NULL); VectorSet(offset, 0, 7, ent->viewheight-8); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); VectorMA(start, 8192, forward, end); tr = gi.trace(start, NULL, NULL, end, ent, MASK_SHOT); if (tr.ent) e = tr.ent; if (e && e->inuse && (e->health > 0) && (level.time > ent->msg_time)) { if (PM_MonsterHasPilot(e)) e = e->owner; else if (!e->client) return; if (IsAlly(ent, e)) { gi.centerprintf(ent, "Ally: %s\n", e->client->pers.netname); ent->msg_time = level.time + 5; } } }
qboolean CanAlly (edict_t *ent, edict_t *other, int range) { // you can't ally with yourself if (ent == other) return false; if (!ValidAlly(ent) || !ValidAlly(other)) { //gi.dprintf("no4\n"); return false; } // check for max allies // alianza con la mitad del server activo (vrxchile v1.3) // si uno de los dos tiene una alianza con mas de la mitad de los jugadores activos, no se pueden aliar. if ( ((numAllies(ent) + 1) > ActivePlayers()/2) || ((numAllies(other) + 1) > ActivePlayers()/2) ) return false; // are we already allied? if (IsAlly(ent, other)) return false; // vrxchile v1.3 encourages alliances ASAP. // are we out of range? /*if (range && (entdist(ent, other) > range)) return false;*/ // can we see each other? /*if (range && !visible(ent, other)) return false;*/ // only allow allies that are close in level // FIXME: we should get an average or median player level if there are >1 allies if (abs(ent->myskills.level - other->myskills.level) > ALLY_MAX_LEVEL_DELTA) { //gi.dprintf("no3\n"); return false; } // only allow allies when their level isn't too high, and server has enough players /*if ((ent->myskills.level > AveragePlayerLevel()*1.5) || (other->myskills.level > AveragePlayerLevel()*1.5) || (ActivePlayers() < 6)) { //gi.dprintf("no1\n"); return false; }*/ //4.5 only allow allies if they have the same combat preferences //if (ent->myskills.respawns != other->myskills.respawns) if (!invasion->value && !pvm->value && !ffa->value) // pvp, always allow no matter the preferences. return true; if (((ent->myskills.respawns & HOSTILE_PLAYERS) != (other->myskills.respawns & HOSTILE_PLAYERS)) || ((ent->myskills.respawns & HOSTILE_MONSTERS) != (other->myskills.respawns & HOSTILE_MONSTERS))) { //gi.dprintf("no2\n"); return false; } return true; }
void Alliance::Neutral(int32_t allianceid) { if (IsNeutral(allianceid)) return; if (IsAlly(allianceid)) UnAlly(allianceid); if (IsEnemy(allianceid)) UnEnemy(allianceid); m_neutral.push_back(allianceid); Alliance * temp = m_main->m_alliances->AllianceById(allianceid); temp->SendAllianceMessage("Alliance [" + temp->m_name + "] recognizes Diplomatic Relationship with us as Neutral.", false, false); }
void ShowAllyMenu (edict_t *ent) { int i; int j = 0; edict_t *temp; //Don't bother displaying the menu if alliances are disabled if (!allies->value) { safe_cprintf(ent, PRINT_HIGH, "Alliances are disabled.\n"); return; } // alliance only work in pvp mode if (!ValidAllyMode()) { safe_cprintf(ent, PRINT_HIGH, "Alliances are disabled.\n"); return; } if (!ShowMenu(ent)) return; clearmenu(ent); addlinetomenu(ent, "Currently allied with:", MENU_GREEN_CENTERED); addlinetomenu(ent, " ", 0); for_each_player(temp, i) { if (IsAlly(ent, temp)) { //Add player to the list addlinetomenu(ent, va(" %s", temp->myskills.player_name), 0); ++j; } } //Menu footer addlinetomenu(ent, " ", 0); addlinetomenu(ent, "Add Ally", 1); addlinetomenu(ent, "Remove Ally", 2); addlinetomenu(ent, "Exit", 666); //Set handler setmenuhandler(ent, ShowAllyMenu_handler); //Set current line ent->client->menustorage.currentline = 6 + j; //Display the menu showmenu(ent); }
void wormhole_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (!other || !other->inuse) return; // point to monster's pilot if (PM_MonsterHasPilot(other)) other = other->activator; if ((other == self->creator) || IsAlly(self->creator, other)) { float time; // can't enter wormhole with the flag if (HasFlag(other)) return; // can't enter wormhole while being hurt if (other->lasthurt + DAMAGE_ESCAPE_DELAY > level.time) return; // can't enter wormhole while cursed (this includes healing, bless) if (que_typeexists(other->curses, -1)) return; // can't stay in wormhole long if we're warring if (SPREE_WAR == true && SPREE_DUDE == other) time = 10.0; else time = BLACKHOLE_EXIT_TIME; // reset railgun sniper frames other->client->refire_frames = 0; VortexRemovePlayerSummonables(other); V_RestoreMorphed(other, 50); // un-morph other->flags |= FL_WORMHOLE; other->movetype = MOVETYPE_NOCLIP; other->svflags |= SVF_NOCLIENT; other->client->wormhole_time = level.time + BLACKHOLE_EXIT_TIME; // must exit wormhole by this time self->nextthink = level.time + FRAMETIME; // close immediately } }
void Alliance::Enemy(int32_t allianceid, bool skip /* = false*/) { if (IsEnemy(allianceid)) return; enemyactioncooldown = unixtime() + 1000*60*60*24; if (IsNeutral(allianceid)) UnNeutral(allianceid); if (IsAlly(allianceid)) UnAlly(allianceid); m_enemies.push_back(allianceid); if (skip) return; //send global message Alliance * temp = m_main->m_alliances->AllianceById(allianceid); m_main->MassMessage("Alliance " + this->m_name + " declares war against alliance " + temp->m_name + ". Diplomatic Relationship between each other alters to Hostile automatically."); temp->Enemy(m_allianceid, true); temp->SendAllianceMessage("Alliance [" + m_name + "] recognizes Diplomatic Relationship with us as Enemy.", false, false); }
void ShowRemoveAllyMenu (edict_t *ent) { int i; int j = 0; edict_t *temp; if (!ShowMenu(ent)) return; clearmenu(ent); addlinetomenu(ent, "Select a player:", MENU_GREEN_CENTERED); addlinetomenu(ent, " ", 0); for_each_player(temp, i) { if (IsAlly(ent, temp)) { //Add player to the list addlinetomenu(ent, va(" %s", temp->myskills.player_name), GetClientNumber(temp)); ++j; } } //Menu footer addlinetomenu(ent, " ", 0); addlinetomenu(ent, "Exit", 666); //Set handler setmenuhandler(ent, ShowRemoveAllyMenu_handler); //Set current line ent->client->menustorage.currentline = 4 + j; //Display the menu showmenu(ent); }
/*UNUSED*/ int Material(board_t board, int player) { Coord crd; int column; int score[2]; /* each side's score */ int ally, enemy, playerBlocked = 1, opponentBlocked = 1; /* Check for win or tie situations: */ /* Since getMoves doesn't provide any moves that leave the king at CHECK, if there aren't any moves, it is MATE */ for (int k = 0; k < BOARD_SIZE*BOARD_SIZE; k++) { crd.i_coord = (int)mod(k, BOARD_SIZE); crd.j_coord = k / BOARD_SIZE; ally = IsAlly(GetContentOfCoord(board, crd), player); enemy = IsEnemy(GetContentOfCoord(board, crd), player); if (GetContentOfCoord(board, crd) != EMPTY) { if (ally > 0 && canMoveThisTool(board, crd) == 1) playerBlocked = 0; if (enemy > 0 && canMoveThisTool(board, crd) == 1) opponentBlocked = 0; } } if (playerBlocked && !opponentBlocked) return -1000000; else if (playerBlocked && opponentBlocked) return -999999; else if (opponentBlocked) return 1000000; /* this is the first pass: set up pawnRow, piecesScoreValue, and pawnsScoreValue. */ for (int i = 0; i < 10; ++i) { // Pawns are set to impossible locations. pawnRow[LIGHT][i] = BOARD_SIZE; pawnRow[DARK][i] = -1; } piecesScoreValue[LIGHT] = 0; piecesScoreValue[DARK] = 0; pawnsScoreValue[LIGHT] = 0; pawnsScoreValue[DARK] = 0; for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { crd.i_coord = i; crd.j_coord = j; if (GetContentOfCoord(board, crd) == EMPTY) continue; if (GetContentOfCoord(board, crd) == WHITE_P || GetContentOfCoord(board, crd) == BLACK_P) { pawnsScoreValue[getColorInLightOrDark(board, crd)] += piece_value[0]; // reminder: int piece_value[6] = {100, 300, 300, 500, 900, 0}; column = i + 1; /* add 1 because of the extra column in the array */ if (getColorInLightOrDark(board, crd) == LIGHT) { if (pawnRow[LIGHT][column] > j) pawnRow[LIGHT][column] = j; } else { if (pawnRow[DARK][column] < j) pawnRow[DARK][column] = j; } } else piecesScoreValue[getColorInLightOrDark(board, crd)] += piece_value[(int)get_eToolFromType(GetContentOfCoord(board, crd))]; } } /* this is the second pass: evaluate each piece */ score[LIGHT] = piecesScoreValue[LIGHT] + pawnsScoreValue[LIGHT]; score[DARK] = piecesScoreValue[DARK] + pawnsScoreValue[DARK]; for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { crd.i_coord = i; crd.j_coord = j; if (GetContentOfCoord(board, crd) == EMPTY) continue; if (getColorInLightOrDark(board, crd) == LIGHT) { char tool = GetContentOfCoord(board, crd); if (tool == WHITE_P) score[LIGHT] += scoreWhitePawns(crd); else if (tool == WHITE_N) score[LIGHT] += knightBonus[i][j]; else if (tool == WHITE_B) score[LIGHT] += bishopBonus[i][j]; else if (tool == WHITE_R) { if (pawnRow[LIGHT][i + 1] == BOARD_SIZE) { if (pawnRow[DARK][i + 1] == -1) score[LIGHT] += ROOK_OPEN_FILE_BONUS; else score[LIGHT] += ROOK_SEMI_OPEN_FILE_BONUS; } if (j == 6) score[LIGHT] += ROOK_ON_SEVENTH_BONUS; } else if (tool == WHITE_K) { if (piecesScoreValue[DARK] <= 1200) score[LIGHT] += kingEndGameBonus[i][j]; else score[LIGHT] += scoreWhiteKing(crd); } } else // DARK { char tool = GetContentOfCoord(board, crd); if (tool == BLACK_P) score[DARK] += scoreBlackPawns(crd); else if (tool == BLACK_N) score[DARK] += knightBonus[i][BOARD_SIZE - 1 - j]; else if (tool == BLACK_B) score[DARK] += bishopBonus[i][BOARD_SIZE - 1 - j]; else if (tool == BLACK_R) { if (pawnRow[DARK][i + 1] == -1) { if (pawnRow[LIGHT][i + 1] == BOARD_SIZE) score[DARK] += ROOK_OPEN_FILE_BONUS; else score[DARK] += ROOK_SEMI_OPEN_FILE_BONUS; } if (j == 1) score[DARK] += ROOK_ON_SEVENTH_BONUS; } else if (tool == BLACK_K) { if (piecesScoreValue[LIGHT] <= 1200) score[DARK] += kingEndGameBonus[i][BOARD_SIZE - 1 - j]; else score[DARK] += scoreBlackKing(crd); } } } } /* the score[] array is set, now return the score relative to the side to move */ if (player == WHITE_PLAYER) return score[LIGHT]; return score[DARK]; }
void MinerGob::SetTarget(Gid gid, WCoord wx, WCoord wy, WCoord wxCenter, WCoord wyCenter, TCoord tcRadius, WCoord wcMoveDistPerUpdate) { if (gid == kgidNull) { // If the target is Galaxite then translate this command into a MineCommand FogMap *pfogm = gsim.GetLevel()->GetFogMap(); if (pfogm->GetGalaxite(TcFromWc(wx), TcFromWc(wy)) != 0) { // Play mine sfx - this is called in a move so the general unit // move sound will also be called, and the mine sound is currently // no different. Needs to somehow be an attack but SimUI.cpp // only checks for mobile units as targets. //if (m_pplr == gpplrLocal) // gsndm.PlaySfx(m_pmnrc->sfxMine); Message msg; memset(&msg, 0, sizeof(msg)); msg.mid = kmidMineCommand; msg.MineCommand.gidTarget = gid; msg.MineCommand.wptTarget.wx = wx; msg.MineCommand.wptTarget.wy = wy; msg.smidReceiver = m_gid; gcmdq.Enqueue(&msg); return; } // If target is not Galaxite let the MobileUnitGob handle command MobileUnitGob::SetTarget(gid, wx, wy, wxCenter, wyCenter, tcRadius, wcMoveDistPerUpdate); return; } // If the target no longer exists, discard the command Gob *pgobTarget = ggobm.GetGob(gid); if (pgobTarget == NULL) return; // If target is not a friendly processor let the MobileUnitGob handle command differentiation if (pgobTarget->GetType() != kgtProcessor || !IsAlly(pgobTarget->GetSide())) { MobileUnitGob::SetTarget(gid, wx, wy, wxCenter, wyCenter, tcRadius, wcMoveDistPerUpdate); return; } // Play deliver sfx gsndm.PlaySfx(ksfxGalaxMinerDeliver); // Flash the target Gob if (m_pplr == gpplrLocal) pgobTarget->Flash(); Message msg; memset(&msg, 0, sizeof(msg)); msg.mid = kmidDeliverCommand; msg.MineCommand.gidTarget = gid; msg.MineCommand.wptTarget.wx = wx; msg.MineCommand.wptTarget.wy = wy; msg.smidReceiver = m_gid; gcmdq.Enqueue(&msg); }