cp_event.c

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 
00024 */
00025 
00026 #include "../cl_shared.h"
00027 #include "../../shared/parse.h"
00028 #include "cp_campaign.h"
00029 #include "cp_time.h"
00030 
00031 static linkedList_t *eventMails = NULL;
00032 
00045 eventMail_t* CL_GetEventMail (const char *id, qboolean createCopy)
00046 {
00047     int i;
00048     linkedList_t* list;
00049     eventMail_t* listMail;
00050 
00051     if (!createCopy) {
00052         for (i = 0; i < ccs.numEventMails; i++)
00053             if (!strcmp(ccs.eventMails[i].id, id))
00054                 return &ccs.eventMails[i];
00055 
00056         list = eventMails;
00057         while (list) {
00058             listMail = (eventMail_t *)list->data;
00059             if (!strcmp(listMail->id, id))
00060                 return listMail;
00061             list = list->next;
00062         }
00063 
00064         return NULL;
00065     } else {
00066         /* create a copy of the static eventmails */
00067         eventMail_t *eventMail = NULL, *newEventMail;
00068 
00069         /* search the static mails - and only the static ones! */
00070         for (i = 0; i < ccs.numEventMails; i++)
00071             if (!strcmp(ccs.eventMails[i].id, id)) {
00072                 eventMail = &ccs.eventMails[i];
00073                 break;
00074             }
00075 
00076         if (!eventMail)
00077             return NULL;
00078 
00079         newEventMail = Mem_PoolAlloc(sizeof(*newEventMail), cp_campaignPool, 0);
00080         if (!newEventMail)
00081             return NULL;
00082 
00083         /* don't !! free the original pointers here */
00084         *newEventMail = *eventMail;
00085         LIST_AddPointer(&eventMails, newEventMail);
00086         /* make sure, that you set a unique eventmail->id and eventmail->body now */
00087         return newEventMail;
00088     }
00089 }
00090 
00095 void CL_FreeDynamicEventMail (void)
00096 {
00097     /* the pointers are not freed, this is done with the
00098      * pool clear in CL_ResetSinglePlayerData */
00099     LIST_Delete(&eventMails);
00100 }
00101 
00114 eventMail_t* CL_NewEventMail (const char *id, const char *newID, const char *body)
00115 {
00116     eventMail_t* mail;
00117 
00118     assert(id);
00119     assert(newID);
00120 
00121     mail = CL_GetEventMail(id, qtrue);
00122     if (!mail)
00123         return NULL;
00124 
00125     /* cp_campaignPool is freed with every new game in CL_ResetSinglePlayerData */
00126     mail->id = Mem_PoolStrDup(newID, cp_campaignPool, 0);
00127 
00128     /* maybe we want to use the old body */
00129     if (body)
00130         mail->body = Mem_PoolStrDup(body, cp_campaignPool, 0);
00131 
00132     return mail;
00133 }
00134 
00136 static const value_t eventMail_vals[] = {
00137     {"subject", V_TRANSLATION_STRING, offsetof(eventMail_t, subject), 0},
00138     {"from", V_TRANSLATION_STRING, offsetof(eventMail_t, from), 0},
00139     {"to", V_TRANSLATION_STRING, offsetof(eventMail_t, to), 0},
00140     {"cc", V_TRANSLATION_STRING, offsetof(eventMail_t, cc), 0},
00141     {"date", V_TRANSLATION_STRING, offsetof(eventMail_t, date), 0},
00142     {"body", V_TRANSLATION_STRING, offsetof(eventMail_t, body), 0},
00143     {"icon", V_CLIENT_HUNK_STRING, offsetof(eventMail_t, icon), 0},
00144     {"model", V_CLIENT_HUNK_STRING, offsetof(eventMail_t, model), 0},
00145 
00146     {NULL, 0, 0, 0}
00147 };
00148 
00153 void CL_ParseEventMails (const char *name, const char **text)
00154 {
00155     const char *errhead = "CL_ParseEventMails: unexpected end of file (mail ";
00156     eventMail_t *eventMail;
00157     const value_t *vp;
00158     const char *token;
00159 
00160     if (ccs.numEventMails >= MAX_EVENTMAILS) {
00161         Com_Printf("CL_ParseEventMails: mail def \"%s\" with same name found, second ignored\n", name);
00162         return;
00163     }
00164 
00165     /* initialize the eventMail */
00166     eventMail = &ccs.eventMails[ccs.numEventMails++];
00167     memset(eventMail, 0, sizeof(*eventMail));
00168 
00169     Com_DPrintf(DEBUG_CLIENT, "...found eventMail %s\n", name);
00170     eventMail->id = Mem_PoolStrDup(name, cp_campaignPool, 0);
00171 
00172     /* get it's body */
00173     token = Com_Parse(text);
00174 
00175     if (!*text || *token != '{') {
00176         Com_Printf("CL_ParseEventMails: eventMail def \"%s\" without body ignored\n", name);
00177         ccs.numEventMails--;
00178         return;
00179     }
00180 
00181     do {
00182         token = Com_EParse(text, errhead, name);
00183         if (!*text)
00184             break;
00185         if (*token == '}')
00186             break;
00187 
00188         /* check for some standard values */
00189         for (vp = eventMail_vals; vp->string; vp++)
00190             if (!strcmp(token, vp->string)) {
00191                 /* found a definition */
00192                 token = Com_EParse(text, errhead, name);
00193                 if (!*text)
00194                     return;
00195 
00196                 switch (vp->type) {
00197                 case V_TRANSLATION_STRING:
00198                     token++;
00199                 case V_CLIENT_HUNK_STRING:
00200                     Mem_PoolStrDupTo(token, (char**) ((char*)eventMail + (int)vp->ofs), cp_campaignPool, 0);
00201                     break;
00202                 default:
00203                     Com_EParseValue(eventMail, token, vp->type, vp->ofs, vp->size);
00204                     break;
00205                 }
00206                 break;
00207             }
00208 
00209         if (!vp->string) {
00210             Com_Printf("CL_ParseEventMails: unknown token \"%s\" ignored (mail %s)\n", token, name);
00211             Com_EParse(text, errhead, name);
00212         }
00213     } while (*text);
00214 }
00215 
00216 void CP_CheckCampaignEvents (void)
00217 {
00218     const campaignEvents_t *events;
00219     int i;
00220 
00221     assert(ccs.curCampaign);
00222 
00223     /* no events for the current campaign */
00224     if (!ccs.curCampaign->events)
00225         return;
00226 
00227     /* no events in that definition */
00228     if (!ccs.curCampaign->events->numCampaignEvents)
00229         return;
00230 
00231     events = ccs.curCampaign->events;
00232     for (i = 0; i < events->numCampaignEvents; i++) {
00233         const campaignEvent_t *event = &events->campaignEvents[i];
00234         if (event->interest <= ccs.overallInterest) {
00235             RS_MarkStoryLineEventResearched(event->tech);
00236         }
00237     }
00238 }
00239 
00245 const campaignEvents_t *CP_GetEventsByID (const char *name)
00246 {
00247     int i;
00248 
00249     for (i = 0; i < ccs.numCampaignEventDefinitions; i++) {
00250         const campaignEvents_t *events = &ccs.campaignEvents[i];
00251         if (!strcmp(events->id, name)) {
00252             int j;
00253             for (j = 0; j < events->numCampaignEvents; j++) {
00254                 const campaignEvent_t *event = &events->campaignEvents[j];
00255                 if (!RS_GetTechByID(event->tech))
00256                     Sys_Error("Illegal tech '%s' given in events '%s'", event->tech, events->id);
00257             }
00258             return events;
00259         }
00260     }
00261 
00262     return NULL;
00263 }
00264 
00269 void CL_ParseCampaignEvents (const char *name, const char **text)
00270 {
00271     const char *errhead = "CL_ParseCampaignEvents: unexpected end of file (mail ";
00272     const char *token;
00273     campaignEvents_t* events;
00274 
00275     if (ccs.numCampaignEventDefinitions >= MAX_CAMPAIGNS) {
00276         Com_Printf("CL_ParseCampaignEvents: max event def limit hit\n");
00277         return;
00278     }
00279 
00280     token = Com_EParse(text, errhead, name);
00281     if (!*text)
00282         return;
00283 
00284     if (!*text || token[0] != '{') {
00285         Com_Printf("CL_ParseCampaignEvents: event def '%s' without body ignored\n", name);
00286         return;
00287     }
00288 
00289     events = &ccs.campaignEvents[ccs.numCampaignEventDefinitions];
00290     memset(events, 0, sizeof(*events));
00291     Com_DPrintf(DEBUG_CLIENT, "...found events %s\n", name);
00292     events->id = Mem_PoolStrDup(name, cp_campaignPool, 0);
00293     ccs.numCampaignEventDefinitions++;
00294 
00295     do {
00296         campaignEvent_t *event;
00297         token = Com_EParse(text, errhead, name);
00298         if (!*text)
00299             break;
00300         if (*token == '}')
00301             break;
00302 
00303         if (events->numCampaignEvents >= MAX_CAMPAIGNEVENTS) {
00304             Com_Printf("CL_ParseCampaignEvents: max events per event definition limit hit\n");
00305             return;
00306         }
00307 
00308         /* initialize the eventMail */
00309         event = &events->campaignEvents[events->numCampaignEvents++];
00310         memset(event, 0, sizeof(*event));
00311 
00312         Mem_PoolStrDupTo(token, (char**) ((char*)event + (int)offsetof(campaignEvent_t, tech)), cp_campaignPool, 0);
00313 
00314         token = Com_EParse(text, errhead, name);
00315         if (!*text)
00316             return;
00317 
00318         Com_EParseValue(event, token, V_INT, offsetof(campaignEvent_t, interest), sizeof(int));
00319 
00320         if (event->interest < 0)
00321             Sys_Error("Illegal interest value in events definition '%s' for tech '%s'\n", events->id, event->tech);
00322     } while (*text);
00323 }
00324 
00331 void CL_EventAddMail_f (void)
00332 {
00333     const char *eventMailId;
00334     eventMail_t* eventMail;
00335     message_t *m;
00336     char dateBuf[MAX_VAR] = "";
00337 
00338     if (Cmd_Argc() < 2) {
00339         Com_Printf("Usage: %s <event_mail_id>\n", Cmd_Argv(0));
00340         return;
00341     }
00342 
00343     eventMailId = Cmd_Argv(1);
00344 
00345     eventMail = CL_GetEventMail(eventMailId, qfalse);
00346     if (!eventMail) {
00347         Com_Printf("CL_EventAddMail_f: Could not find eventmail with id '%s'\n", eventMailId);
00348         return;
00349     }
00350 
00351     if (!eventMail->from || !eventMail->to || !eventMail->subject || !eventMail->body) {
00352         Com_Printf("CL_EventAddMail_f: mail with id '%s' has incomplete data\n", eventMailId);
00353         return;
00354     }
00355 
00356     if (!eventMail->date) {
00357         dateLong_t date;
00358         CL_DateConvertLong(&ccs.date, &date);
00359         Com_sprintf(dateBuf, sizeof(dateBuf), _("%i %s %02i"),
00360             date.year, Date_GetMonthName(date.month - 1), date.day);
00361         eventMail->date = Mem_PoolStrDup(dateBuf, cp_campaignPool, 0);
00362     }
00363 
00364     /* the subject double %s: see UP_SetMailHeader */
00365     m = MS_AddNewMessage("", va(_("You've got a new mail: %s"), _(eventMail->subject)), qfalse, MSG_EVENT, NULL);
00366     if (m)
00367         m->eventMail = eventMail;
00368     else
00369         Com_Printf("Could not add message with id: %s\n", eventMailId);
00370 }

Generated by  doxygen 1.6.2