2007-01-15 12:09:25 -08:00
|
|
|
/*
|
|
|
|
This file is part of Warzone 2100.
|
|
|
|
Copyright (C) 1999-2004 Eidos Interactive
|
|
|
|
Copyright (C) 2005-2007 Warzone Resurrection Project
|
|
|
|
|
|
|
|
Warzone 2100 is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
Warzone 2100 is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with Warzone 2100; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
2007-06-28 10:47:08 -07:00
|
|
|
/*
|
|
|
|
* MultiGift.c
|
|
|
|
* gifts one player can give to another..
|
|
|
|
* Also home to Deathmatch hardcoded RULES.
|
|
|
|
*/
|
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/framework/frame.h"
|
2006-09-23 10:24:55 -07:00
|
|
|
#include "lib/framework/strres.h"
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/widget/widget.h"
|
|
|
|
#include "objmem.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "console.h"
|
|
|
|
#include "map.h"
|
|
|
|
#include "research.h"
|
|
|
|
#include "power.h"
|
|
|
|
#include "group.h"
|
|
|
|
#include "anim_id.h"
|
|
|
|
#include "hci.h"
|
|
|
|
#include "scriptfuncs.h" // for objectinrange.
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/gamelib/gtime.h"
|
|
|
|
#include "effects.h"
|
|
|
|
#include "lib/sound/audio.h"
|
2007-03-27 11:59:03 -07:00
|
|
|
#include "lib/sound/audio_id.h" // for samples.
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "wrappers.h" // for gameover..
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/script/script.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "scripttabs.h"
|
|
|
|
#include "scriptcb.h"
|
|
|
|
#include "loop.h"
|
2008-07-27 06:38:17 -07:00
|
|
|
#include "transporter.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2006-05-27 09:37:17 -07:00
|
|
|
#include "lib/netplay/netplay.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "multiplay.h"
|
|
|
|
#include "multigifts.h"
|
|
|
|
#include "multiint.h" // for force name.
|
|
|
|
#include "multimenu.h" // for multimenu
|
|
|
|
#include "multistat.h"
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// prototypes
|
2007-05-17 07:00:15 -07:00
|
|
|
|
2008-02-15 12:25:31 -08:00
|
|
|
static void recvGiftDroids (uint8_t from, uint8_t to, uint32_t droidID);
|
2007-12-22 10:51:45 -08:00
|
|
|
static void sendGiftDroids (uint8_t from, uint8_t to);
|
|
|
|
static void giftResearch (uint8_t from, uint8_t to, BOOL send);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// gifts..
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
BOOL recvGift(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
uint8_t type, from, to;
|
|
|
|
int audioTrack;
|
2008-02-15 12:25:31 -08:00
|
|
|
uint32_t droidID;
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-02-13 12:25:12 -08:00
|
|
|
NETbeginDecode(NET_GIFT);
|
2007-12-22 10:51:45 -08:00
|
|
|
NETuint8_t(&type);
|
|
|
|
NETuint8_t(&from);
|
|
|
|
NETuint8_t(&to);
|
2008-02-15 12:25:31 -08:00
|
|
|
NETuint32_t(&droidID);
|
|
|
|
NETend();
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-02-15 12:25:31 -08:00
|
|
|
// Handle the gift depending on what it is
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case RADAR_GIFT:
|
|
|
|
audioTrack = ID_SENSOR_DOWNLOAD;
|
2008-03-24 09:51:17 -07:00
|
|
|
giftRadar(from, to, false);
|
2008-02-15 12:25:31 -08:00
|
|
|
break;
|
|
|
|
case DROID_GIFT:
|
|
|
|
audioTrack = ID_UNITS_TRANSFER;
|
|
|
|
recvGiftDroids(from, to, droidID);
|
|
|
|
break;
|
|
|
|
case RESEARCH_GIFT:
|
|
|
|
audioTrack = ID_TECHNOLOGY_TRANSFER;
|
2008-03-24 09:51:17 -07:00
|
|
|
giftResearch(from, to, false);
|
2008-02-15 12:25:31 -08:00
|
|
|
break;
|
|
|
|
case POWER_GIFT:
|
|
|
|
audioTrack = ID_POWER_TRANSMIT;
|
2008-03-24 09:51:17 -07:00
|
|
|
giftPower(from, to, false);
|
2008-02-15 12:25:31 -08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
debug(LOG_ERROR, "recvGift: Unknown Gift recvd");
|
2008-03-24 09:51:17 -07:00
|
|
|
return false;
|
2008-02-15 12:25:31 -08:00
|
|
|
break;
|
|
|
|
}
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-02-15 12:25:31 -08:00
|
|
|
// If we are on the recieving end play an audio alert
|
|
|
|
if (to == selectedPlayer)
|
|
|
|
{
|
|
|
|
audio_QueueTrack(audioTrack);
|
|
|
|
}
|
2008-03-24 09:51:17 -07:00
|
|
|
return true;
|
2007-12-22 10:51:45 -08:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
BOOL sendGift(uint8_t type, uint8_t to)
|
|
|
|
{
|
|
|
|
int audioTrack;
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
switch (type)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
case RADAR_GIFT:
|
2007-12-22 10:51:45 -08:00
|
|
|
audioTrack = ID_SENSOR_DOWNLOAD;
|
2008-03-24 09:51:17 -07:00
|
|
|
giftRadar(selectedPlayer, to, true);
|
2007-06-28 10:47:08 -07:00
|
|
|
break;
|
|
|
|
case DROID_GIFT:
|
2007-12-22 10:51:45 -08:00
|
|
|
audioTrack = ID_UNITS_TRANSFER;
|
|
|
|
sendGiftDroids(selectedPlayer, to);
|
2007-06-28 10:47:08 -07:00
|
|
|
break;
|
|
|
|
case RESEARCH_GIFT:
|
2007-12-22 10:51:45 -08:00
|
|
|
audioTrack = ID_TECHNOLOGY_TRANSFER;
|
2008-03-24 09:51:17 -07:00
|
|
|
giftResearch(selectedPlayer, to, true);
|
2007-06-28 10:47:08 -07:00
|
|
|
break;
|
|
|
|
case POWER_GIFT:
|
2007-12-22 10:51:45 -08:00
|
|
|
audioTrack = ID_POWER_TRANSMIT;
|
2008-03-24 09:51:17 -07:00
|
|
|
giftPower(selectedPlayer, to, true);
|
2007-06-28 10:47:08 -07:00
|
|
|
break;
|
|
|
|
default:
|
2007-12-22 10:51:45 -08:00
|
|
|
debug( LOG_ERROR, "Unknown Gift sent" );
|
|
|
|
abort();
|
2008-03-24 09:51:17 -07:00
|
|
|
return false;
|
2007-06-28 10:47:08 -07:00
|
|
|
break;
|
|
|
|
}
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
// Play the appropriate audio track
|
|
|
|
audio_QueueTrack(audioTrack);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-03-24 09:51:17 -07:00
|
|
|
return true;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// give radar information
|
2007-12-22 10:51:45 -08:00
|
|
|
void giftRadar(uint8_t from, uint8_t to, BOOL send)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2008-02-15 12:25:31 -08:00
|
|
|
uint32_t dummy = 0;
|
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
hqReward(from, to);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (send)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
uint8_t subType = RADAR_GIFT;
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETbeginEncode(NET_GIFT, NET_ALL_PLAYERS);
|
|
|
|
NETuint8_t(&subType);
|
|
|
|
NETuint8_t(&from);
|
|
|
|
NETuint8_t(&to);
|
2008-02-15 12:25:31 -08:00
|
|
|
NETuint32_t(&dummy);
|
2007-12-22 10:51:45 -08:00
|
|
|
NETend();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-12-22 10:51:45 -08:00
|
|
|
// If we are recieving the gift
|
2007-12-21 16:30:27 -08:00
|
|
|
else if (to == selectedPlayer)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
CONPRINTF(ConsoleString,(ConsoleString,_("%s Gives You A Visibility Report"),
|
|
|
|
getPlayerName(from)));
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-01-22 11:49:03 -08:00
|
|
|
// recvGiftDroid()
|
|
|
|
// We received a droid gift from another player.
|
|
|
|
// NOTICE: the packet is already set-up for decoding via recvGift()
|
|
|
|
//
|
|
|
|
// \param from :player that sent us the droid
|
|
|
|
// \param to :player that should be getting the droid
|
2008-02-15 12:25:31 -08:00
|
|
|
static void recvGiftDroids(uint8_t from, uint8_t to, uint32_t droidID)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2008-01-22 11:49:03 -08:00
|
|
|
DROID *psDroid;
|
2007-12-22 10:51:45 -08:00
|
|
|
|
2008-01-22 11:49:03 -08:00
|
|
|
if (IdToDroid(droidID, from, &psDroid))
|
2007-12-22 10:51:45 -08:00
|
|
|
{
|
2008-01-22 11:49:03 -08:00
|
|
|
giftSingleDroid(psDroid, to);
|
|
|
|
if (to == selectedPlayer)
|
2006-05-27 09:37:17 -07:00
|
|
|
{
|
2008-01-22 11:49:03 -08:00
|
|
|
CONPRINTF(ConsoleString, (ConsoleString, _("%s Gives you a %s"), getPlayerName(from), psDroid->aName));
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
2008-01-22 11:49:03 -08:00
|
|
|
else
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2008-01-22 11:49:03 -08:00
|
|
|
debug(LOG_ERROR, "recvGiftDroids: Bad droid id %d", (int)droidID);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2008-01-22 11:49:03 -08:00
|
|
|
// sendGiftDroids()
|
|
|
|
// We give selected droid(s) as a gift to another player.
|
|
|
|
//
|
|
|
|
// \param from :player that sent us the droid
|
|
|
|
// \param to :player that should be getting the droid
|
2007-12-22 10:51:45 -08:00
|
|
|
static void sendGiftDroids(uint8_t from, uint8_t to)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2008-01-22 11:49:03 -08:00
|
|
|
DROID *next, *psD;
|
|
|
|
uint8_t giftType = DROID_GIFT;
|
|
|
|
uint8_t totalToSend;
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
if (apsDroidLists[from] == NULL)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-01-22 11:49:03 -08:00
|
|
|
/*
|
|
|
|
* Work out the number of droids to send. As well as making sure they are
|
|
|
|
* selected we also need to make sure they will NOT put the receiving player
|
|
|
|
* over their droid limit.
|
|
|
|
*/
|
|
|
|
|
|
|
|
for (totalToSend = 0, psD = apsDroidLists[from];
|
|
|
|
psD && getNumDroids(to) + totalToSend < getMaxDroids(to) && totalToSend != UINT8_MAX;
|
|
|
|
psD = psD->psNext)
|
2007-12-22 10:51:45 -08:00
|
|
|
{
|
2008-01-22 11:49:03 -08:00
|
|
|
if (psD->selected)
|
|
|
|
++totalToSend;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* We must send one droid at a time, due to the fact that giftSingleDroid()
|
|
|
|
* does its own net calls.
|
|
|
|
*/
|
2007-12-22 10:51:45 -08:00
|
|
|
|
2008-01-22 11:49:03 -08:00
|
|
|
for (psD = apsDroidLists[from]; psD && totalToSend != 0; psD = next)
|
|
|
|
{
|
|
|
|
// Store the next droid in the list as the list may change
|
|
|
|
next = psD->psNext;
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-07-27 06:38:17 -07:00
|
|
|
if (psD->droidType == DROID_TRANSPORTER
|
|
|
|
&& !transporterIsEmpty(psD))
|
2007-12-22 10:51:45 -08:00
|
|
|
{
|
2008-07-27 06:38:17 -07:00
|
|
|
CONPRINTF(ConsoleString, (ConsoleString, _("Tried to give away a non-empty %s - but this is not allowed."), psD->aName));
|
2008-01-22 11:49:03 -08:00
|
|
|
continue;
|
2007-12-22 10:51:45 -08:00
|
|
|
}
|
2008-01-22 11:49:03 -08:00
|
|
|
if (psD->selected)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2008-01-22 11:49:03 -08:00
|
|
|
NETbeginEncode(NET_GIFT, NET_ALL_PLAYERS);
|
|
|
|
NETuint8_t(&giftType);
|
|
|
|
NETuint8_t(&from);
|
|
|
|
NETuint8_t(&to);
|
|
|
|
// Add the droid to the packet
|
|
|
|
NETuint32_t(&psD->id);
|
|
|
|
NETend();
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-01-22 11:49:03 -08:00
|
|
|
// Hand over the droid on our sidde
|
|
|
|
giftSingleDroid(psD, to);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-01-22 11:49:03 -08:00
|
|
|
// Decrement the number of droids left to send
|
|
|
|
--totalToSend;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// give technologies.
|
2007-12-22 10:51:45 -08:00
|
|
|
static void giftResearch(uint8_t from, uint8_t to, BOOL send)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
PLAYER_RESEARCH *pR, *pRto;
|
2008-02-15 12:25:31 -08:00
|
|
|
int i;
|
|
|
|
uint32_t dummy = 0;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
pR = asPlayerResList[from];
|
|
|
|
pRto = asPlayerResList[to];
|
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
// For each topic
|
|
|
|
for (i = 0; i < numResearch; i++)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
// If they have it and we don't research it
|
|
|
|
if (IsResearchCompleted(&pR[i])
|
|
|
|
&& !IsResearchCompleted(&pRto[i]))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
MakeResearchCompleted(&pRto[i]);
|
2008-03-24 09:51:17 -07:00
|
|
|
researchResult(i, to, false, NULL);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (send)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
uint8_t giftType = RESEARCH_GIFT;
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETbeginEncode(NET_GIFT, NET_ALL_PLAYERS);
|
|
|
|
NETuint8_t(&giftType);
|
|
|
|
NETuint8_t(&from);
|
|
|
|
NETuint8_t(&to);
|
2008-02-15 12:25:31 -08:00
|
|
|
NETuint32_t(&dummy);
|
2007-12-22 10:51:45 -08:00
|
|
|
NETend();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-12-21 16:30:27 -08:00
|
|
|
else if (to == selectedPlayer)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
CONPRINTF(ConsoleString,(ConsoleString,_("%s Gives You Technology Documents"),getPlayerName(from) ));
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// give Power
|
2007-12-22 10:51:45 -08:00
|
|
|
void giftPower(uint8_t from, uint8_t to, BOOL send)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
UDWORD gifval;
|
2008-02-15 12:25:31 -08:00
|
|
|
uint32_t dummy = 0;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (from == ANYPLAYER)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
gifval = OILDRUM_POWER;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
// Give 1/3 of our power away
|
2008-02-15 13:48:51 -08:00
|
|
|
gifval = getPower(from) / 3;
|
2007-06-28 10:47:08 -07:00
|
|
|
usePower(from, gifval);
|
|
|
|
}
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
addPower(to, gifval);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (send)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
uint8_t giftType = POWER_GIFT;
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETbeginEncode(NET_GIFT, NET_ALL_PLAYERS);
|
|
|
|
NETuint8_t(&giftType);
|
|
|
|
NETuint8_t(&from);
|
|
|
|
NETuint8_t(&to);
|
2008-02-15 12:25:31 -08:00
|
|
|
NETuint32_t(&dummy);
|
2007-12-22 10:51:45 -08:00
|
|
|
NETend();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-12-21 16:30:27 -08:00
|
|
|
else if (to == selectedPlayer)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
CONPRINTF(ConsoleString,(ConsoleString,_("%s Gives You Power"),getPlayerName(from)));
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// alliance code......
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
void requestAlliance(uint8_t from, uint8_t to, BOOL prop, BOOL allowAudio)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
alliances[from][to] = ALLIANCE_REQUESTED; // We've asked
|
|
|
|
alliances[to][from] = ALLIANCE_INVITATION; // They've been invited
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
|
|
|
|
CBallFrom = from;
|
|
|
|
CBallTo = to;
|
2007-12-22 10:51:45 -08:00
|
|
|
eventFireCallbackTrigger((TRIGGER_TYPE) CALL_ALLIANCEOFFER);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (to == selectedPlayer)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
CONPRINTF(ConsoleString,(ConsoleString,_("%s Requests An Alliance With You"),getPlayerName(from)));
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (allowAudio)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
audio_QueueTrack(ID_ALLIANCE_OFF);
|
|
|
|
}
|
|
|
|
}
|
2007-12-22 10:51:45 -08:00
|
|
|
else if (from == selectedPlayer)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
CONPRINTF(ConsoleString,(ConsoleString,_("You Invite %s To Form An Alliance"),getPlayerName(to)));
|
|
|
|
if (allowAudio)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
audio_QueueTrack(ID_ALLIANCE_OFF);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (prop)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2008-03-24 09:51:17 -07:00
|
|
|
sendAlliance(from, to, ALLIANCE_REQUESTED, false);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
void breakAlliance(uint8_t p1, uint8_t p2, BOOL prop, BOOL allowAudio)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2006-11-03 17:11:26 -08:00
|
|
|
char tm1[128];
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (alliances[p1][p2] == ALLIANCE_FORMED)
|
2006-05-27 09:37:17 -07:00
|
|
|
{
|
2008-05-25 06:46:49 -07:00
|
|
|
sstrcpy(tm1, getPlayerName(p1));
|
2007-04-01 13:15:46 -07:00
|
|
|
CONPRINTF(ConsoleString,(ConsoleString,_("%s Breaks The Alliance With %s"),tm1,getPlayerName(p2) ));
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (allowAudio && (p1 == selectedPlayer || p2 == selectedPlayer))
|
2006-05-27 09:37:17 -07:00
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
audio_QueueTrack(ID_ALLIANCE_BRO);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
alliances[p1][p2] = ALLIANCE_BROKEN;
|
|
|
|
alliances[p2][p1] = ALLIANCE_BROKEN;
|
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (prop)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2008-03-24 09:51:17 -07:00
|
|
|
sendAlliance(p1, p2, ALLIANCE_BROKEN, false);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
void formAlliance(uint8_t p1, uint8_t p2, BOOL prop, BOOL allowAudio, BOOL allowNotification)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
DROID *psDroid;
|
2006-11-03 17:11:26 -08:00
|
|
|
char tm1[128];
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
// Don't add message if already allied
|
|
|
|
if (bMultiPlayer && alliances[p1][p2] != ALLIANCE_FORMED && allowNotification)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2008-05-25 06:46:49 -07:00
|
|
|
sstrcpy(tm1, getPlayerName(p1));
|
2007-12-21 16:30:27 -08:00
|
|
|
CONPRINTF(ConsoleString,(ConsoleString,_("%s Forms An Alliance With %s"),tm1,getPlayerName(p2)));
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
alliances[p1][p2] = ALLIANCE_FORMED;
|
|
|
|
alliances[p2][p1] = ALLIANCE_FORMED;
|
|
|
|
|
2006-09-21 13:42:48 -07:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (allowAudio && (p1 == selectedPlayer || p2== selectedPlayer))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
audio_QueueTrack(ID_ALLIANCE_ACC);
|
|
|
|
}
|
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (bMultiPlayer && prop)
|
2006-05-27 09:37:17 -07:00
|
|
|
{
|
2008-03-24 09:51:17 -07:00
|
|
|
sendAlliance(p1, p2, ALLIANCE_FORMED, false);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
// Not campaign and alliances are transitive
|
|
|
|
if ((bMultiPlayer || game.type == SKIRMISH) && game.alliance == ALLIANCES_TEAMS)
|
2006-09-21 13:42:48 -07:00
|
|
|
{
|
2008-03-24 09:51:17 -07:00
|
|
|
giftRadar(p1, p2, false);
|
|
|
|
giftRadar(p2, p1, false);
|
2006-09-21 13:42:48 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
// Clear out any attacking orders
|
2008-03-24 09:51:17 -07:00
|
|
|
turnOffMultiMsg(true);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
for (psDroid = apsDroidLists[p1]; psDroid; psDroid = psDroid->psNext) // from -> to
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-11-10 09:31:37 -08:00
|
|
|
if (psDroid->order == DORDER_ATTACK
|
2007-12-21 16:30:27 -08:00
|
|
|
&& psDroid->psTarget
|
|
|
|
&& psDroid->psTarget->player == p2)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
orderDroid(psDroid, DORDER_STOP);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
2007-12-21 16:30:27 -08:00
|
|
|
for (psDroid = apsDroidLists[p2]; psDroid; psDroid = psDroid->psNext) // to -> from
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-11-10 09:31:37 -08:00
|
|
|
if (psDroid->order == DORDER_ATTACK
|
2007-12-21 16:30:27 -08:00
|
|
|
&& psDroid->psTarget
|
|
|
|
&& psDroid->psTarget->player == p1)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
orderDroid(psDroid,DORDER_STOP);
|
|
|
|
}
|
|
|
|
}
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-03-24 09:51:17 -07:00
|
|
|
turnOffMultiMsg(false);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
void sendAlliance(uint8_t from, uint8_t to, uint8_t state, int32_t value)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
NETbeginEncode(NET_ALLIANCE, NET_ALL_PLAYERS);
|
|
|
|
NETuint8_t(&from);
|
|
|
|
NETuint8_t(&to);
|
|
|
|
NETuint8_t(&state);
|
|
|
|
NETint32_t(&value);
|
|
|
|
NETend();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
BOOL recvAlliance(BOOL allowAudio)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
uint8_t to, from, state;
|
|
|
|
int32_t value;
|
|
|
|
|
2008-02-13 12:25:12 -08:00
|
|
|
NETbeginDecode(NET_ALLIANCE);
|
2007-12-22 10:51:45 -08:00
|
|
|
NETuint8_t(&from);
|
|
|
|
NETuint8_t(&to);
|
|
|
|
NETuint8_t(&state);
|
|
|
|
NETint32_t(&value);
|
|
|
|
NETend();
|
|
|
|
|
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case ALLIANCE_NULL:
|
|
|
|
break;
|
|
|
|
case ALLIANCE_REQUESTED:
|
2008-03-24 09:51:17 -07:00
|
|
|
requestAlliance(from, to, false, allowAudio);
|
2007-12-22 10:51:45 -08:00
|
|
|
break;
|
|
|
|
case ALLIANCE_FORMED:
|
2008-03-24 09:51:17 -07:00
|
|
|
formAlliance(from, to, false, allowAudio, true);
|
2007-12-22 10:51:45 -08:00
|
|
|
break;
|
|
|
|
case ALLIANCE_BROKEN:
|
2008-03-24 09:51:17 -07:00
|
|
|
breakAlliance(from, to, false, allowAudio);
|
2007-12-22 10:51:45 -08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
debug(LOG_ERROR, "Unknown alliance state recvd.");
|
2008-03-24 09:51:17 -07:00
|
|
|
return false;
|
2007-12-22 10:51:45 -08:00
|
|
|
break;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2008-03-24 09:51:17 -07:00
|
|
|
return true;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// add an artifact on destruction if required.
|
2007-12-24 03:59:47 -08:00
|
|
|
void technologyGiveAway(const STRUCTURE *pS)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
int i;
|
|
|
|
uint8_t count = 1;
|
|
|
|
uint32_t x, y;
|
|
|
|
FEATURE *pF = NULL;
|
|
|
|
FEATURE_TYPE type = FEAT_GEN_ARTE;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
// If a factory which is our responsibility got destroyed
|
|
|
|
if (pS->pStructureType->type == REF_FACTORY
|
|
|
|
&& myResponsibility(pS->player))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-15 07:39:29 -08:00
|
|
|
x = map_coord(pS->pos.x);
|
|
|
|
y = map_coord(pS->pos.y);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
// Pick a tile to place the artifact
|
|
|
|
if (!pickATileGen(&x, &y, LOOK_FOR_EMPTY_TILE, zonedPAT))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2008-03-24 09:51:17 -07:00
|
|
|
ASSERT(false, "technologyGiveAway: Unable to find a free location");
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
// Get the feature offset
|
|
|
|
for(i = 0; i < numFeatureStats && asFeatureStats[i].subType != FEAT_GEN_ARTE; i++);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
// 'Build' the artifact
|
2008-03-24 09:51:17 -07:00
|
|
|
pF = buildFeature((asFeatureStats + i), world_coord(x), world_coord(y), false);
|
2007-12-22 10:51:45 -08:00
|
|
|
if (pF)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
pF->player = pS->player;
|
|
|
|
}
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETbeginEncode(NET_ARTIFACTS, NET_ALL_PLAYERS);
|
2007-12-24 03:59:47 -08:00
|
|
|
{
|
|
|
|
/* Make sure that we don't have to violate the constness of pS.
|
|
|
|
* Since the nettype functions aren't const correct when sending
|
|
|
|
*/
|
|
|
|
uint8_t player = pS->player;
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETuint8_t(&count);
|
|
|
|
NETenum(&type);
|
|
|
|
NETuint32_t(&x);
|
|
|
|
NETuint32_t(&y);
|
|
|
|
NETuint32_t(&pF->id);
|
2007-12-24 03:59:47 -08:00
|
|
|
NETuint8_t(&player);
|
|
|
|
}
|
2007-12-22 10:51:45 -08:00
|
|
|
NETend();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// loooosseeeerrr gifts
|
|
|
|
// if the player is losing then give a simple gift.
|
|
|
|
|
|
|
|
#define GIFTFREQ (1000*(60*5)) // every 5 mins tops..
|
|
|
|
|
2008-03-28 16:28:44 -07:00
|
|
|
static void addLoserGifts(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
static UDWORD lastgift = 0;
|
|
|
|
int count, i;
|
|
|
|
uint8_t player = ONEPLAYER;
|
|
|
|
uint8_t quantity;
|
|
|
|
uint32_t x, y;
|
2007-06-28 10:47:08 -07:00
|
|
|
FEATURE *pF;
|
2007-12-22 10:51:45 -08:00
|
|
|
FEATURE_TYPE type = FEAT_OIL_DRUM;
|
2007-06-28 10:47:08 -07:00
|
|
|
STRUCTURE *psStruct;
|
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
if (lastgift > gameTime)
|
|
|
|
lastgift = 0; // might be a restart
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
// Player has no power, so give the player some oil
|
2008-02-15 13:48:51 -08:00
|
|
|
if (apsStructLists[selectedPlayer] && getPower(selectedPlayer) < 10)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
// Only proceed if it's been a while
|
|
|
|
if (gameTime - lastgift < GIFTFREQ)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
// Only proceed if no powergen
|
|
|
|
for (psStruct = apsStructLists[selectedPlayer];
|
2007-12-22 10:51:45 -08:00
|
|
|
psStruct && psStruct->pStructureType->type != REF_POWER_GEN;
|
|
|
|
psStruct = psStruct->psNext);
|
2007-12-21 16:30:27 -08:00
|
|
|
if (psStruct)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
lastgift = gameTime;
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
for (i = 0;
|
|
|
|
i < numFeatureStats && asFeatureStats[i].subType != FEAT_OIL_DRUM;
|
|
|
|
i++);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
quantity = rand() % 5 + 1;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETbeginEncode(NET_ARTIFACTS, NET_ALL_PLAYERS);
|
|
|
|
NETuint8_t(&quantity);
|
|
|
|
NETenum(&type);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
for (count = 0; count < quantity; count++)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
x = map_coord(apsStructLists[selectedPlayer]->pos.x);
|
|
|
|
y = map_coord(apsStructLists[selectedPlayer]->pos.y);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
if (!pickATileGen(&x, &y, LOOK_FOR_EMPTY_TILE, zonedPAT))
|
|
|
|
{
|
2008-03-24 09:51:17 -07:00
|
|
|
ASSERT(false, "addlosergifts: Unable to find a free location");
|
2007-12-22 10:51:45 -08:00
|
|
|
}
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETlogEntry("gift", 0, 0);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-03-24 09:51:17 -07:00
|
|
|
pF = buildFeature((asFeatureStats + i), world_coord(x), world_coord(y), false);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETuint32_t(&x);
|
|
|
|
NETuint32_t(&y);
|
|
|
|
NETuint32_t(&pF->id);
|
|
|
|
NETuint8_t(&player);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
if (pF)
|
|
|
|
{
|
|
|
|
// Flag for multiplayer artifacts
|
|
|
|
pF->player = player;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETend();
|
2007-06-28 10:47:08 -07:00
|
|
|
audio_QueueTrack(ID_GIFT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-01-06 13:55:23 -08:00
|
|
|
/** Sends a build order for the given feature type to all players
|
2008-01-09 04:18:36 -08:00
|
|
|
* \param subType the type of feature to build
|
2008-01-06 13:55:23 -08:00
|
|
|
* \param x,y the coordinates to place the feature at
|
|
|
|
*/
|
|
|
|
void sendMultiPlayerFeature(FEATURE_TYPE subType, uint32_t x, uint32_t y)
|
|
|
|
{
|
|
|
|
NETbeginEncode(NET_FEATURES, NET_ALL_PLAYERS);
|
|
|
|
{
|
|
|
|
NETenum(&subType);
|
|
|
|
NETuint32_t(&x);
|
|
|
|
NETuint32_t(&y);
|
|
|
|
}
|
|
|
|
NETend();
|
|
|
|
}
|
|
|
|
|
|
|
|
void recvMultiPlayerFeature()
|
|
|
|
{
|
|
|
|
FEATURE_TYPE subType;
|
|
|
|
uint32_t x, y;
|
|
|
|
unsigned int i;
|
|
|
|
|
2008-02-13 12:25:12 -08:00
|
|
|
NETbeginDecode(NET_FEATURES);
|
2008-01-06 13:55:23 -08:00
|
|
|
{
|
|
|
|
NETenum(&subType);
|
|
|
|
NETuint32_t(&x);
|
|
|
|
NETuint32_t(&y);
|
|
|
|
}
|
|
|
|
NETend();
|
|
|
|
|
|
|
|
// Find the feature stats list that contains the feature type we want to build
|
|
|
|
for (i = 0; i < numFeatureStats; ++i)
|
|
|
|
{
|
|
|
|
// If we found the correct feature type
|
2008-01-06 14:44:42 -08:00
|
|
|
if (asFeatureStats[i].subType == subType)
|
2008-01-06 13:55:23 -08:00
|
|
|
{
|
|
|
|
// Create a feature of the specified type at the given location
|
2008-03-24 09:51:17 -07:00
|
|
|
buildFeature(&asFeatureStats[i], x, y, false);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2008-01-06 13:55:23 -08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// splatter artifact gifts randomly about.
|
2007-12-22 10:51:45 -08:00
|
|
|
void addMultiPlayerRandomArtifacts(uint8_t quantity, FEATURE_TYPE type)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
FEATURE *pF;
|
|
|
|
int i, count;
|
|
|
|
uint32_t x, y;
|
|
|
|
uint8_t player = ANYPLAYER;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETbeginEncode(NET_ARTIFACTS, NET_ALL_PLAYERS);
|
|
|
|
NETuint8_t(&quantity);
|
|
|
|
NETenum(&type);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
for(i = 0; i < numFeatureStats && asFeatureStats[i].subType != type; i++);
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
ASSERT(mapWidth > 20, "map not big enough");
|
|
|
|
ASSERT(mapHeight > 20, "map not big enough");
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
for (count = 0; count < quantity; count++)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
// Between 10 and mapwidth - 10
|
|
|
|
x = (rand() % (mapWidth - 20)) + 10;
|
|
|
|
y = (rand() % (mapHeight - 20)) + 10;
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
if (!pickATileGen(&x, &y, LOOK_FOR_EMPTY_TILE, zonedPAT))
|
|
|
|
{
|
2008-03-24 09:51:17 -07:00
|
|
|
ASSERT(false, "addMultiPlayerRandomArtifacts: Unable to find a free location");
|
2007-12-22 10:51:45 -08:00
|
|
|
}
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-03-24 09:51:17 -07:00
|
|
|
pF = buildFeature(asFeatureStats + i, world_coord(x), world_coord(y), false);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETuint32_t(&x);
|
|
|
|
NETuint32_t(&y);
|
|
|
|
NETuint32_t(&pF->id);
|
|
|
|
NETuint8_t(&player);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
if (pF)
|
|
|
|
{
|
|
|
|
pF->player = player;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETend();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// ///////////////////////////////////////////////////////////////
|
2007-12-22 10:51:45 -08:00
|
|
|
BOOL addOilDrum(uint8_t count)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
addMultiPlayerRandomArtifacts(count, FEAT_OIL_DRUM);
|
2008-03-24 09:51:17 -07:00
|
|
|
return true;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// ///////////////////////////////////////////////////////////////
|
|
|
|
// receive splattered artifacts
|
2007-12-22 10:51:45 -08:00
|
|
|
void recvMultiPlayerRandomArtifacts()
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-22 10:51:45 -08:00
|
|
|
int count, i;
|
|
|
|
uint8_t quantity, player;
|
|
|
|
uint32_t tx,ty;
|
|
|
|
uint32_t ref;
|
|
|
|
FEATURE_TYPE type;
|
|
|
|
FEATURE *pF;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2008-02-13 12:25:12 -08:00
|
|
|
NETbeginDecode(NET_ARTIFACTS);
|
2007-12-22 10:51:45 -08:00
|
|
|
NETuint8_t(&quantity);
|
|
|
|
NETenum(&type);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
for (i = 0; i < numFeatureStats && asFeatureStats[i].subType != type; i++);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
for (count = 0; count < quantity; count++)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2008-03-17 14:57:01 -07:00
|
|
|
MAPTILE *psTile;
|
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
NETuint32_t(&tx);
|
|
|
|
NETuint32_t(&ty);
|
|
|
|
NETuint32_t(&ref);
|
|
|
|
NETuint8_t(&player);
|
2007-12-24 03:59:47 -08:00
|
|
|
|
2008-03-17 14:57:01 -07:00
|
|
|
if (!tileOnMap(tx, ty))
|
|
|
|
{
|
|
|
|
debug(LOG_ERROR, "recvMultiPlayerRandomArtifacts: Bad tile coordinates (%u,%u)", tx, ty);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
psTile = mapTile(tx, ty);
|
|
|
|
if (!psTile || psTile->psObject != NULL)
|
|
|
|
{
|
|
|
|
debug(LOG_ERROR, "recvMultiPlayerRandomArtifacts: Already something at (%u,%u)!", tx, ty);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-03-24 09:51:17 -07:00
|
|
|
pF = buildFeature((asFeatureStats + i), world_coord(tx), world_coord(ty), false);
|
2007-12-22 10:51:45 -08:00
|
|
|
if (pF)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
pF->id = ref;
|
2007-12-22 10:51:45 -08:00
|
|
|
pF->player = player;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
2008-03-17 14:57:01 -07:00
|
|
|
NETend();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// ///////////////////////////////////////////////////////////////
|
2007-12-21 16:30:27 -08:00
|
|
|
void giftArtifact(UDWORD owner, UDWORD x, UDWORD y)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
PLAYER_RESEARCH *pO,*pR;
|
|
|
|
UDWORD topic=0;
|
|
|
|
pR = asPlayerResList[selectedPlayer];
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-12-22 10:51:45 -08:00
|
|
|
if (owner < MAX_PLAYERS)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
pO = asPlayerResList[owner];
|
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
for (topic = numResearch; topic > 0; topic--)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
if (IsResearchCompleted(&pO[topic])
|
|
|
|
&& !IsResearchPossible(&pR[topic]))
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
MakeResearchPossible(&pR[topic]);
|
2007-04-03 10:31:30 -07:00
|
|
|
CONPRINTF(ConsoleString,(ConsoleString,_("You Discover Blueprints For %s"),
|
|
|
|
getName(asResearch[topic].pName)));
|
2008-01-05 13:26:44 -08:00
|
|
|
|
|
|
|
break;
|
2006-05-27 09:37:17 -07:00
|
|
|
}
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ///////////////////////////////////////////////////////////////
|
2006-09-13 02:09:05 -07:00
|
|
|
void processMultiPlayerArtifacts(void)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
static UDWORD lastCall;
|
|
|
|
FEATURE *pF,*pFN;
|
|
|
|
UDWORD x,y,pl;
|
2007-03-16 09:20:16 -07:00
|
|
|
Vector3i position;
|
2008-03-24 09:51:17 -07:00
|
|
|
BOOL found=false;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
// only do this every now and again.
|
|
|
|
if(lastCall > gameTime)lastCall= 0;
|
|
|
|
if ( (gameTime - lastCall) <2000)
|
2006-05-27 09:37:17 -07:00
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
lastCall = gameTime;
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
addLoserGifts();
|
|
|
|
|
|
|
|
for(pF = apsFeatureLists[0]; pF ; pF = pFN)
|
|
|
|
{
|
|
|
|
pFN = pF->psNext;
|
|
|
|
// artifacts
|
|
|
|
if(pF->psStats->subType == FEAT_GEN_ARTE)
|
2006-05-27 09:37:17 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
found = objectInRange((BASE_OBJECT *)apsDroidLists[selectedPlayer], pF->pos.x, pF->pos.y, (TILE_UNITS+(TILE_UNITS/3)) );
|
2007-06-28 10:47:08 -07:00
|
|
|
if(found)
|
|
|
|
{
|
2007-12-15 07:39:29 -08:00
|
|
|
position.x = pF->pos.x; // Add an effect
|
|
|
|
position.z = pF->pos.y;
|
|
|
|
position.y = pF->pos.z;
|
2008-03-24 09:51:17 -07:00
|
|
|
addEffect(&position,EFFECT_EXPLOSION,EXPLOSION_TYPE_DISCOVERY,false,NULL,false);
|
2006-05-27 09:37:17 -07:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
x = pF->pos.x;
|
|
|
|
y = pF->pos.y;
|
|
|
|
pl= pF->player;
|
|
|
|
removeFeature(pF); // remove artifact+ send info.
|
|
|
|
giftArtifact(pl,x,y); // reward player.
|
|
|
|
pF->player = 0;
|
|
|
|
audio_QueueTrack( ID_SOUND_ARTIFACT_RECOVERED );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-26 11:14:05 -07:00
|
|
|
/* Ally team members with each other */
|
|
|
|
void createTeamAlliances(void)
|
2006-09-21 13:42:48 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
int i, j;
|
2006-09-21 13:42:48 -07:00
|
|
|
|
2006-09-26 11:14:05 -07:00
|
|
|
debug(LOG_WZ, "Creating teams");
|
2006-09-21 13:42:48 -07:00
|
|
|
|
2007-12-21 16:30:27 -08:00
|
|
|
for (i = 0; i < MAX_PLAYERS; i++)
|
2006-09-21 13:42:48 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
for (j = 0; j < MAX_PLAYERS; j++)
|
2006-09-21 13:42:48 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
if (i != j
|
|
|
|
&& playerTeam[i] == playerTeam[j] // Wto different players belonging to the same team
|
|
|
|
&& !aiCheckAlliances(i, j)
|
|
|
|
&& playerTeam[i] >= 0
|
|
|
|
&& game.skDiff[i]
|
|
|
|
&& game.skDiff[j]) // Not allied and not ignoring teams
|
2006-09-27 19:11:19 -07:00
|
|
|
{
|
2007-12-21 16:30:27 -08:00
|
|
|
// Create silently
|
2008-03-24 09:51:17 -07:00
|
|
|
formAlliance(i, j, false, false, false);
|
2006-09-27 19:11:19 -07:00
|
|
|
}
|
2006-09-21 13:42:48 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|