boolean P_SetMobjState (mobj_t *mobj, statenum_t state) { state_t *st; if (state == S_NULL) { mobj->state = S_NULL; P_RemoveMobj (mobj); return false; } st = &states[state]; mobj->state = st; mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; if (st->action) /* call action functions when the state is set */ st->action (mobj); mobj->latecall = NULL; /* make sure it doesn't come back to life... */ return true; }
boolean P_SetMobjState ( mobj_t* mobj, statenum_t state ) { state_t* st; do { if (state == S_NULL) { mobj->state = (state_t *) S_NULL; P_RemoveMobj (mobj); return false; } st = &states[state]; mobj->state = st; mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; // Modified handling. // Call action functions when the state is set if (st->action.acp1) st->action.acp1(mobj); state = st->nextstate; } while (!mobj->tics); return true; }
void T_LaserThinker(laserthinker_t* laserthinker) { laser_t* laser = laserthinker->laser; laser->dist += 64; // laser reached its destination? if(laser->dist >= laser->distmax) { // reached the end? if(!laser->next) { P_RemoveThinker(&laserthinker->thinker); // fade out the laser puff P_FadeMobj(laserthinker->dest, -24, 0, 0); } else laserthinker->laser = laser->next; // advance to next laser point // remove marker and free laser P_RemoveMobj(laser->marker); Z_Free(laser); } else { // update laser's location laser->x1 += laser->slopex; laser->y1 += laser->slopey; laser->z1 += laser->slopez; } }
// // P_UnArchiveThinkers // void P_UnArchiveThinkers (void) { byte tclass; thinker_t* currentthinker; thinker_t* next; mobj_t* mobj; // remove all the current thinkers currentthinker = thinkercap.next; while (currentthinker != &thinkercap) { next = currentthinker->next; if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) P_RemoveMobj ((mobj_t *)currentthinker); else Z_Free (currentthinker); currentthinker = next; } P_InitThinkers (); // read in saved thinkers while (1) { tclass = *save_p++; switch (tclass) { case tc_end: return; // end of list case tc_mobj: PADSAVEP(); mobj = (mobj_t*)Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL); memcpy (mobj, save_p, sizeof(*mobj)); save_p += sizeof(*mobj); mobj->state = &states[(int)mobj->state]; mobj->target = NULL; if (mobj->player) { mobj->player = &players[(int)mobj->player-1]; mobj->player->mo = mobj; } P_SetThingPosition (mobj); mobj->info = &mobjinfo[mobj->type]; mobj->floorz = mobj->subsector->sector->floorheight; mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; P_AddThinker (&mobj->thinker); break; default: I_Error ("Unknown tclass %i in savegame",tclass); } } }
boolean EV_ThingSpawn(byte *args, boolean fog) { int tid; angle_t angle; mobj_t *mobj; mobj_t *newMobj; mobj_t *fogMobj; mobjtype_t moType; int searcher; boolean success; fixed_t z; success = false; searcher = -1; tid = args[0]; moType = TranslateThingType[args[1]]; if(nomonsters && (mobjinfo[moType].flags & MF_COUNTKILL)) { // Don't spawn monsters if -nomonsters return false; } angle = (int) args[2] << 24; while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { if(mobjinfo[moType].flags2 & MF2_FLOATBOB) { z = mobj->z - mobj->floorz; } else { z = mobj->z; } newMobj = P_SpawnMobj(mobj->x, mobj->y, z, moType); if(P_TestMobjLocation(newMobj) == false) { // Didn't fit P_RemoveMobj(newMobj); } else { newMobj->angle = angle; if(fog == true) { fogMobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z + TELEFOGHEIGHT, MT_TFOG); S_StartSound(SFX_TELEPORT, fogMobj); } newMobj->flags2 |= MF2_DROPPED; // Don't respawn if(newMobj->flags2 & MF2_FLOATBOB) { newMobj->special1 = newMobj->z - newMobj->floorz; } success = true; } } return success; }
// // P_UnArchiveThinkers // void P_UnArchiveThinkers (void) { byte tclass; thinker_t* currentthinker; thinker_t* next; mobj_t* mobj; // remove all the current thinkers currentthinker = thinkercap.next; while (currentthinker != &thinkercap) { next = currentthinker->next; if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) P_RemoveMobj ((mobj_t *)currentthinker); else Z_Free (currentthinker); currentthinker = next; } P_InitThinkers (); // read in saved thinkers while (1) { tclass = saveg_read8(); switch (tclass) { case tc_end: return; // end of list case tc_mobj: saveg_read_pad(); mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL); saveg_read_mobj_t(mobj); mobj->target = NULL; mobj->tracer = NULL; P_SetThingPosition (mobj); mobj->info = &mobjinfo[mobj->type]; mobj->floorz = mobj->subsector->sector->floorheight; mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; P_AddThinker (&mobj->thinker); break; default: I_Error ("Unknown tclass %i in savegame",tclass); } } }
dboolean G_CheckSpot(int playernum, mapthing_t* mthing) { fixed_t x; fixed_t y; subsector_t* ss; angle_t an; mobj_t* mo; int i; if(!players[playernum].mo) { // first spawn of level, before corpses for(i = 0; i < playernum; i++) { if((players[i].mo->x == INT2F(mthing->x)) && (players[i].mo->y == INT2F(mthing->y))) { return false; } } return true; } x = INT2F(mthing->x); y = INT2F(mthing->y); if(!P_CheckPosition(players[playernum].mo, x, y)) { return false; } // flush an old corpse if needed if(bodyqueslot >= BODYQUESIZE) { P_RemoveMobj(bodyque[bodyqueslot % BODYQUESIZE]); } bodyque[bodyqueslot%BODYQUESIZE] = players[playernum].mo; bodyqueslot++; // spawn a teleport fog ss = R_PointInSubsector(x, y); // 20120402 villsa - force angle_t typecast to avoid issues on 64-bit machines an = ANG45 * (angle_t)(mthing->angle / 45); mo = P_SpawnMobj( x + 20*dcos(an), y + 20*dsin(an), ss->sector->floorheight, MT_TELEPORTFOG ); if(players[playernum].viewz != 1) { S_StartSound(mo, sfx_telept); // don't start sound on first frame } return true; }
boolean P_SetMobjStateNF(mobj_t * mobj, statenum_t state) { state_t *st; if (state == S_NULL) { // Remove mobj mobj->state = (state_t *) S_NULL; P_RemoveMobj(mobj); return (false); } st = &states[state]; mobj->state = st; mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; return (true); }
boolean EV_ThingRemove(int tid) { mobj_t *mobj; int searcher; boolean success; success = false; searcher = -1; while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { if(mobj->type == MT_BRIDGE) { A_BridgeRemove(mobj); return true; } P_RemoveMobj(mobj); success = true; } return success; }
boolean P_SetMobjState ( mobj_t* mobj, statenum_t state ) { state_t* st; int cycle_counter = 0; do { if (state == S_NULL) { mobj->state = (state_t *) S_NULL; P_RemoveMobj (mobj); return false; } st = &states[state]; mobj->state = st; mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; // Modified handling. // Call action functions when the state is set if (st->action.acp3) st->action.acp3(mobj, NULL, NULL); // [crispy] let pspr action pointers get called from mobj states state = st->nextstate; if (cycle_counter++ > MOBJ_CYCLE_LIMIT) { I_Error("P_SetMobjState: Infinite state cycle detected!"); } } while (!mobj->tics); return true; }
static CMD(SpawnThing) { int id = 0; player_t *player; mobj_t *thing; fixed_t x, y, z; if(gamestate != GS_LEVEL) { return; } if(!param[0]) { return; } if(netgame) { return; } id = datoi(param[0]); if(id >= NUMMOBJTYPES || id < 0) { return; } player = &players[consoleplayer]; x = player->mo->x + FixedMul(INT2F(64) + mobjinfo[id].radius, dcos(player->mo->angle)); y = player->mo->y + FixedMul(INT2F(64) + mobjinfo[id].radius, dsin(player->mo->angle)); z = player->mo->z; thing = P_SpawnMobj(x, y, z, id); if(thing->info->spawnstate == S_000) { P_RemoveMobj(thing); return; } thing->angle = player->mo->angle; }
void P_UnArchiveMobjs(void) { mobj_t* current; mobj_t* next; mobj_t* mobj; int i; // remove all the current thinkers current = mobjhead.next; while(current != &mobjhead) { next = current->next; P_RemoveMobj(current); current = next; } saveg_setup_mobjread(); mobjhead.next = mobjhead.prev = &mobjhead; for(i = 0; i < savegmobjnum; i++) { mobj = savegmobj[i].mobj; saveg_read_pad(); saveg_read_mobj_t(mobj); if(!saveg_read_marker(SAVEGAME_MOBJ)) I_Error("P_UnArchiveMobjs: Mobj read is inconsistent\nfile offset: %i\nmobj count: %i", save_offset, savegmobjnum); P_SetThingPosition(mobj); P_LinkMobj(mobj); mobj->info = &mobjinfo[mobj->type]; } saveg_read_pad(); }
void P_XYMovement(mobj_t *mo) { player_t *player; fixed_t xmove, ymove; if (!mo->momx && !mo->momy) { if (mo->flags & MF_SKULLFLY) { // the skull slammed into something mo->flags &= ~MF_SKULLFLY; mo->momx = mo->momy = mo->momz = 0; P_SetMobjState(mo, (statenum_t)mo->info->spawnstate); } return; } player = mo->player; if (mo->type == MT_ROCKET) { if (puffcount++ > 1) P_SpawnPuff(mo->x, mo->y, mo->z, mo->angle); } if (mo->momx > MAXMOVE) mo->momx = MAXMOVE; else if (mo->momx < -MAXMOVE) mo->momx = -MAXMOVE; if (mo->momy > MAXMOVE) mo->momy = MAXMOVE; else if (mo->momy < -MAXMOVE) mo->momy = -MAXMOVE; xmove = mo->momx; ymove = mo->momy; do { fixed_t ptryx, ptryy; if (xmove > MAXMOVE / 2 || ymove > MAXMOVE / 2 || xmove < -MAXMOVE / 2 || ymove < -MAXMOVE / 2) { ptryx = mo->x + xmove / 2; ptryy = mo->y + ymove / 2; xmove >>= 1; ymove >>= 1; } else { ptryx = mo->x + xmove; ptryy = mo->y + ymove; xmove = ymove = 0; } if (!P_TryMove(mo, ptryx, ptryy)) { // blocked move if (mo->player) { // try to slide along it P_SlideMove(mo); } else if (mo->flags & MF_MISSILE) { // explode a missile if (ceilingline && ceilingline->backsector && ceilingline->backsector->ceilingpic == skyflatnum && mo->z > ceilingline->backsector->ceilingheight) { // Hack to prevent missiles exploding // against the sky. // Does not handle sky floors. shootingsky = true; P_RemoveMobj(mo); return; } P_ExplodeMissile(mo); } else { mo->momx = mo->momy = 0; } } }
// // P_UnArchiveThinkers // void P_UnArchiveThinkers(void) { thinker_t *currentthinker = thinkers[th_all].next; // remove all the current thinkers while (currentthinker != &thinkers[th_all]) { thinker_t *next = currentthinker->next; if (currentthinker->function == P_MobjThinker || currentthinker->function == MusInfoThinker) { P_RemoveMobj((mobj_t *)currentthinker); P_RemoveThinkerDelayed(currentthinker); } else Z_Free(currentthinker); currentthinker = next; } P_InitThinkers(); // remove all bloodsplats for (int i = 0; i < numsectors; i++) { bloodsplat_t *splat = sectors[i].splatlist; while (splat) { bloodsplat_t *next = splat->snext; P_UnsetBloodSplatPosition(splat); splat = next; } } r_bloodsplats_total = 0; thingindex = 0; // read in saved thinkers while (true) { byte tclass = saveg_read8(); switch (tclass) { case tc_end: return; // end of list case tc_mobj: { mobj_t *mobj = Z_Calloc(1, sizeof(*mobj), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_mobj_t(mobj); mobj->info = &mobjinfo[mobj->type]; P_SetThingPosition(mobj); mobj->thinker.function = (mobj->type == MT_MUSICSOURCE ? MusInfoThinker : P_MobjThinker); P_AddThinker(&mobj->thinker); mobj->colfunc = mobj->info->colfunc; mobj->altcolfunc = mobj->info->altcolfunc; P_SetShadowColumnFunction(mobj); thingindex = MIN(thingindex + 1, TARGETLIMIT - 1); break; } case tc_bloodsplat: { bloodsplat_t *splat = calloc(1, sizeof(*splat)); saveg_read_pad(); saveg_read_bloodsplat_t(splat); if (r_bloodsplats_total < r_bloodsplats_max) { splat->width = spritewidth[splat->patch]; splat->sector = R_PointInSubsector(splat->x, splat->y)->sector; P_SetBloodSplatPosition(splat); splat->colfunc = (splat->blood == FUZZYBLOOD ? fuzzcolfunc : bloodsplatcolfunc); r_bloodsplats_total++; } break; } default: I_Error("This savegame is invalid."); } } }
void P_SetupLevel(int map, skill_t skill) { int i; static char lumpname[16]; int lumpnum; mobj_t *mobj; extern int cy; M_ClearRandom(); P_LoadingPlaque(); D_printf("P_SetupLevel(%i,%i)\n", map, skill); totalkills = totalitems = totalsecret = 0; for(i = 0; i < MAXPLAYERS; i++) players[i].killcount = players[i].secretcount = players[i].itemcount = 0; Z_CheckHeap(mainzone); Z_CheckHeap(refzone); Z_FreeTags(mainzone); P_InitThinkers(); // // look for a regular (development) map first // lumpname[0] = 'M'; lumpname[1] = 'A'; lumpname[2] = 'P'; lumpname[3] = '0' + map / 10; lumpname[4] = '0' + map % 10; lumpname[5] = 0; lumpnum = W_GetNumForName(lumpname); // note: most of this ordering is important P_LoadBlockMap(lumpnum+ML_BLOCKMAP); P_LoadVertexes(lumpnum+ML_VERTEXES); P_LoadSectors(lumpnum+ML_SECTORS); P_LoadSideDefs(lumpnum+ML_SIDEDEFS); P_LoadLineDefs(lumpnum+ML_LINEDEFS); P_LoadSubsectors(lumpnum+ML_SSECTORS); P_LoadNodes(lumpnum+ML_NODES); P_LoadSegs(lumpnum+ML_SEGS); rejectmatrix = W_CacheLumpNum(lumpnum + ML_REJECT, PU_LEVEL); P_GroupLines(); deathmatch_p = deathmatchstarts; P_LoadThings(lumpnum + ML_THINGS); // // if deathmatch, randomly spawn the active players // if(netgame == gt_deathmatch) { for(i = 0; i < MAXPLAYERS; i++) { if(playeringame[i]) { // must give a player spot before deathmatchspawn mobj = P_SpawnMobj(deathmatchstarts[0].x << 16 ,deathmatchstarts[0].y << 16, 0, MT_PLAYER); players[i].mo = mobj; G_DeathMatchSpawnPlayer(i); P_RemoveMobj(mobj); } } } // set up world state P_SpawnSpecials(); ST_InitEveryLevel(); cy = 4; iquehead = iquetail = 0; gamepaused = false; }
void P_XYMovement (mobj_t* mo) { fixed_t ptryx; fixed_t ptryy; player_t* player; fixed_t xmove; fixed_t ymove; if (!mo->momx && !mo->momy) { if (mo->flags & MF_SKULLFLY) { // the skull slammed into something mo->flags &= ~MF_SKULLFLY; mo->momx = mo->momy = mo->momz = 0; P_SetMobjState (mo, mo->info->spawnstate); } return; } player = mo->player; if (mo->momx > MAXMOVE) mo->momx = MAXMOVE; else if (mo->momx < -MAXMOVE) mo->momx = -MAXMOVE; if (mo->momy > MAXMOVE) mo->momy = MAXMOVE; else if (mo->momy < -MAXMOVE) mo->momy = -MAXMOVE; xmove = mo->momx; ymove = mo->momy; do { if (xmove > MAXMOVE/2 || ymove > MAXMOVE/2) { ptryx = mo->x + xmove/2; ptryy = mo->y + ymove/2; xmove >>= 1; ymove >>= 1; } else { ptryx = mo->x + xmove; ptryy = mo->y + ymove; xmove = ymove = 0; } if (!P_TryMove (mo, ptryx, ptryy)) { // blocked move if (mo->player) { // try to slide along it P_SlideMove (mo); } else if (mo->flags & MF_MISSILE) { // explode a missile if (ceilingline && ceilingline->backsector && ceilingline->backsector->ceilingpic == skyflatnum) { // Hack to prevent missiles exploding // against the sky. // Does not handle sky floors. P_RemoveMobj (mo); return; } P_ExplodeMissile (mo); } else mo->momx = mo->momy = 0; } } while (xmove || ymove);
// // P_UnArchiveThinkers // void P_v19_UnArchiveThinkers(void) { byte tclass; thinker_t *currentthinker; thinker_t *next; mobj_t *mobj; // remove all the current thinkers currentthinker = thinkercap.next; while(currentthinker != &thinkercap) { next = currentthinker->next; if(currentthinker->function == P_MobjThinker) P_RemoveMobj((mobj_t *) currentthinker); else Z_Free(currentthinker); currentthinker = next; } P_InitThinkers(); // read in saved thinkers while(1) { tclass = *save_p++; switch (tclass) { case tc_end: return; // end of list case tc_mobj: PADSAVEP(); mobj = Z_Malloc(sizeof(*mobj), PU_LEVEL, NULL); memset(mobj, 0, sizeof(*mobj)); //memcpy (mobj, save_p, sizeof(*mobj)); //P_MobjConverter(mobj, (savemobj_t*) save_p, false); //memcpy(mobj, save_p, sizeof(*mobj)); SV_ReadMobj(mobj); //save_p += sizeof(savemobj_t); mobj->state = &states[(int) mobj->state]; mobj->target = NULL; if(mobj->player) { int pnum = (int) mobj->player - 1; mobj->player = &players[pnum]; mobj->dplayer = mobj->player->plr; mobj->dplayer->mo = mobj; mobj->dplayer->clAngle = mobj->angle; mobj->dplayer->clLookDir = 0; } P_SetThingPosition(mobj); mobj->info = &mobjinfo[mobj->type]; mobj->floorz = mobj->subsector->sector->floorheight; mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function = P_MobjThinker; P_AddThinker(&mobj->thinker); break; default: Con_Error("Unknown tclass %i in savegame", tclass); } } }
void P_UnArchiveThinkers (void) { thinker_t *th; mobj_t **mobj_p; // killough 2/14/98: Translation table size_t size; // killough 2/14/98: size of or index into table totallive = 0; // killough 3/26/98: Load boss brain state memcpy(&brain, save_p, sizeof brain); save_p += sizeof brain; // remove all the current thinkers for (th = thinkercap.next; th != &thinkercap; ) { thinker_t *next = th->next; if (th->function == P_MobjThinker) { P_RemoveMobj ((mobj_t *) th); P_RemoveThinkerDelayed(th); // fix mobj leak } else Z_Free (th); th = next; } P_InitThinkers (); // killough 2/14/98: count number of thinkers by skipping through them { byte *sp = save_p; // save pointer and skip header for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { // skip all entries, adding up count PADSAVEP(); save_p += sizeof(mobj_t);//e6y } if (*--save_p != tc_end) I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p); // first table entry special: 0 maps to NULL *(mobj_p = malloc(size * sizeof *mobj_p)) = 0; // table of pointers save_p = sp; // restore save pointer } // read in saved thinkers for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { mobj_t *mobj = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL); // killough 2/14/98 -- insert pointers to thinkers into table, in order: mobj_p[size] = mobj; PADSAVEP(); memcpy (mobj, save_p, sizeof(mobj_t)); save_p += sizeof(mobj_t); mobj->state = states + (int) mobj->state; if (mobj->player) (mobj->player = &players[(int) mobj->player - 1]) -> mo = mobj; P_SetThingPosition (mobj); mobj->info = &mobjinfo[mobj->type]; // killough 2/28/98: // Fix for falling down into a wall after savegame loaded: // mobj->floorz = mobj->subsector->sector->floorheight; // mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function = P_MobjThinker; P_AddThinker (&mobj->thinker); if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL | MF_CORPSE))) totallive++; } // killough 2/14/98: adjust target and tracer fields, plus // lastenemy field, to correctly point to mobj thinkers. // NULL entries automatically handled by first table entry. // // killough 11/98: use P_SetNewTarget() to set fields for (th = thinkercap.next ; th != &thinkercap ; th=th->next) { P_SetNewTarget(&((mobj_t *) th)->target, mobj_p[P_GetMobj(((mobj_t *)th)->target,size)]); P_SetNewTarget(&((mobj_t *) th)->tracer, mobj_p[P_GetMobj(((mobj_t *)th)->tracer,size)]); P_SetNewTarget(&((mobj_t *) th)->lastenemy, mobj_p[P_GetMobj(((mobj_t *)th)->lastenemy,size)]); } { // killough 9/14/98: restore soundtargets int i; for (i = 0; i < numsectors; i++) { mobj_t *target; memcpy(&target, save_p, sizeof target); save_p += sizeof target; // Must verify soundtarget. See P_ArchiveThinkers. P_SetNewTarget(§ors[i].soundtarget, mobj_p[P_GetMobj(target,size)]); } } free(mobj_p); // free translation table // killough 3/26/98: Spawn icon landings: if (gamemode == commercial) { // P_SpawnBrainTargets overwrites brain.targeton and brain.easy with zero. struct brain_s brain_tmp = brain; // saving P_SpawnBrainTargets(); // old demos with save/load tics should not be affected by this fix if (!prboom_comp[PC_RESET_MONSTERSPAWNER_PARAMS_AFTER_LOADING].state) { brain = brain_tmp; // restoring } } }
//=========================================================================== // P_CheckSpot // Returns false if the player cannot be respawned // at the given mapthing_t spot because something is occupying it // FIXME: Quite a mess! //=========================================================================== boolean P_CheckSpot(int playernum, mapthing_t * mthing, boolean doTeleSpark) { fixed_t x; fixed_t y; unsigned an; mobj_t *mo; #if __JDOOM__ || __JHEXEN__ subsector_t *ss; #endif #if __JDOOM__ int i; #endif #if __JHERETIC__ || __JHEXEN__ mapthing_t faraway; boolean using_dummy = false; #endif #if __JDOOM__ if(!players[playernum].plr->mo) { // first spawn of level, before corpses for(i = 0; i < playernum; i++) { if(players[i].plr->mo && players[i].plr->mo->x == mthing->x << FRACBITS && players[i].plr->mo->y == mthing->y << FRACBITS) return false; } return true; } #endif x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; #if __JHERETIC__ || __JHEXEN__ if(!players[playernum].plr->mo) { // The player doesn't have a mobj. Let's create a dummy. faraway.x = faraway.y = DDMAXSHORT; P_SpawnPlayer(&faraway, playernum); using_dummy = true; } players[playernum].plr->mo->flags2 &= ~MF2_PASSMOBJ; #endif if(!P_CheckPosition(players[playernum].plr->mo, x, y)) { #if __JHERETIC__ || __JHEXEN__ players[playernum].plr->mo->flags2 |= MF2_PASSMOBJ; if(using_dummy) { P_RemoveMobj(players[playernum].plr->mo); players[playernum].plr->mo = NULL; } #endif return false; } #if __JHERETIC__ players[playernum].plr->mo->flags2 |= MF2_PASSMOBJ; #endif #if __JHERETIC__ || __JHEXEN__ if(using_dummy) { P_RemoveMobj(players[playernum].plr->mo); players[playernum].plr->mo = NULL; } #endif #if __JDOOM__ G_QueueBody(players[playernum].plr->mo); #endif if(doTeleSpark) { // spawn a teleport fog an = (ANG45 * (mthing->angle / 45)) >> ANGLETOFINESHIFT; #if __JDOOM__ || __JHEXEN__ ss = R_PointInSubsector(x, y); mo = P_SpawnMobj(x + 20 * finecosine[an], y + 20 * finesine[an], ss->sector->floorheight, MT_TFOG); #else // __JHERETIC__ mo = P_SpawnTeleFog(x + 20 * finecosine[an], y + 20 * finesine[an]); #endif // don't start sound on first frame if(players[consoleplayer].plr->viewz != 1) { #ifdef __JHEXEN__ S_StartSound(SFX_TELEPORT, mo); #else S_StartSound(sfx_telept, mo); #endif } } return true; }
void P_UnArchiveThinkers (void) { thinker_t *th; mobj_t **mobj_p; // killough 2/14/98: Translation table size_t size; // killough 2/14/98: size of or index into table totallive = 0; // killough 3/26/98: Load boss brain state memcpy(&brain, save_p, sizeof brain); save_p += sizeof brain; // remove all the current thinkers for (th = thinkercap.next; th != &thinkercap; ) { thinker_t *next = th->next; if (th->function == P_MobjThinker) P_RemoveMobj ((mobj_t *) th); else Z_Free (th); th = next; } P_InitThinkers (); // killough 2/14/98: count number of thinkers by skipping through them { byte *sp = save_p; // save pointer and skip header for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { // skip all entries, adding up count PADSAVEP(); save_p += sizeof(mobj_t); } if (*--save_p != tc_end) I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p); // first table entry special: 0 maps to NULL *(mobj_p = malloc(size * sizeof *mobj_p)) = 0; // table of pointers save_p = sp; // restore save pointer } // read in saved thinkers for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { mobj_t *mobj = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL); // killough 2/14/98 -- insert pointers to thinkers into table, in order: mobj_p[size] = mobj; PADSAVEP(); memcpy (mobj, save_p, sizeof(mobj_t)); save_p += sizeof(mobj_t); mobj->state = states + (unsigned long) mobj->state; if (mobj->player) (mobj->player = &players[(unsigned long) mobj->player - 1]) -> mo = mobj; P_SetThingPosition (mobj); mobj->info = &mobjinfo[mobj->type]; // killough 2/28/98: // Fix for falling down into a wall after savegame loaded: // mobj->floorz = mobj->subsector->sector->floorheight; // mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function = P_MobjThinker; P_AddThinker (&mobj->thinker); if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL | MF_CORPSE))) totallive++; } // killough 2/14/98: adjust target and tracer fields, plus // lastenemy field, to correctly point to mobj thinkers. // NULL entries automatically handled by first table entry. // // killough 11/98: use P_SetNewTarget() to set fields for (th = thinkercap.next ; th != &thinkercap ; th=th->next) { P_SetNewTarget(&((mobj_t *) th)->target, mobj_p[(size_t)((mobj_t *)th)->target]); P_SetNewTarget(&((mobj_t *) th)->tracer, mobj_p[(size_t)((mobj_t *)th)->tracer]); P_SetNewTarget(&((mobj_t *) th)->lastenemy, mobj_p[(size_t)((mobj_t *)th)->lastenemy]); // phares: added two new fields for Sprite Height problem P_SetNewTarget(&((mobj_t *) th)->above_thing, mobj_p[(size_t)((mobj_t *)th)->above_thing]); P_SetNewTarget(&((mobj_t *) th)->below_thing, mobj_p[(size_t)((mobj_t *)th)->below_thing]); } { // killough 9/14/98: restore soundtargets int i; for (i = 0; i < numsectors; i++) { mobj_t *target; memcpy(&target, save_p, sizeof target); save_p += sizeof target; P_SetNewTarget(§ors[i].soundtarget, mobj_p[(size_t) target]); } } free(mobj_p); // free translation table // killough 3/26/98: Spawn icon landings: if (gamemode == commercial) P_SpawnBrainTargets(); }
void P_SetupLevel(int episode, int map, int playermask, skill_t skill) { int i; int parm; char lumpname[9]; char auxName[128]; int lumpnum; mobj_t *mobj; for(i = 0; i < MAXPLAYERS; i++) { players[i].killcount = players[i].secretcount = players[i].itemcount = 0; } players[consoleplayer].viewz = 1; // will be set by player think #ifdef __WATCOMC__ if(i_CDMusic == false) { S_StartSongName("chess", true); // Waiting-for-level-load song } #endif Z_FreeTags(PU_LEVEL, PU_PURGELEVEL-1); P_InitThinkers(); leveltime = 0; if(DevMaps) { sprintf(auxName, "%sMAP%02d.WAD", DevMapsDir, map); W_OpenAuxiliary(auxName); } sprintf(lumpname, "MAP%02d", map); lumpnum = W_GetNumForName(lumpname); // // Begin processing map lumps // Note: most of this ordering is important // P_LoadBlockMap(lumpnum+ML_BLOCKMAP); P_LoadVertexes(lumpnum+ML_VERTEXES); P_LoadSectors(lumpnum+ML_SECTORS); P_LoadSideDefs(lumpnum+ML_SIDEDEFS); P_LoadLineDefs(lumpnum+ML_LINEDEFS); P_LoadSubsectors(lumpnum+ML_SSECTORS); P_LoadNodes(lumpnum+ML_NODES); P_LoadSegs(lumpnum+ML_SEGS); rejectmatrix = W_CacheLumpNum(lumpnum+ML_REJECT, PU_LEVEL); P_GroupLines(); bodyqueslot = 0; po_NumPolyobjs = 0; deathmatch_p = deathmatchstarts; P_LoadThings(lumpnum+ML_THINGS); PO_Init(lumpnum+ML_THINGS); // Initialize the polyobjs P_LoadACScripts(lumpnum+ML_BEHAVIOR); // ACS object code // // End of map lump processing // if(DevMaps) { // Close the auxiliary file, but don't free its loaded lumps. // The next call to W_OpenAuxiliary() will do a full shutdown // of the current auxiliary WAD (free lumps and info lists). W_CloseAuxiliaryFile(); W_UsePrimary(); } // If deathmatch, randomly spawn the active players TimerGame = 0; if(deathmatch) { for (i=0 ; i<MAXPLAYERS ; i++) { if (playeringame[i]) { // must give a player spot before deathmatchspawn mobj = P_SpawnMobj (playerstarts[0][i].x<<16, playerstarts[0][i].y<<16,0, MT_PLAYER_FIGHTER); players[i].mo = mobj; G_DeathMatchSpawnPlayer (i); P_RemoveMobj (mobj); } } parm = M_CheckParm("-timer"); if(parm && parm < myargc-1) { TimerGame = atoi(myargv[parm+1])*35*60; } } // set up world state P_SpawnSpecials (); // build subsector connect matrix // P_ConnectSubsectors (); // Load colormap and set the fullbright flag i = P_GetMapFadeTable(gamemap); W_ReadLump(i, colormaps); if(i == W_GetNumForName("COLORMAP")) { LevelUseFullBright = true; } else { // Probably fog ... don't use fullbright sprites LevelUseFullBright = false; } // preload graphics if (precache) R_PrecacheLevel (); // Check if the level is a lightning level P_InitLightning(); S_StopAllSound(); SN_StopAllSequences(); S_StartSong(gamemap, true); //printf ("free memory: 0x%x\n", Z_FreeMemory()); }
// // P_TouchSpecialThing // void P_TouchSpecialThing(mobj_t* special, mobj_t* toucher) { player_t* player; fixed_t delta; int sound; int i = 0; delta = special->z - toucher->z; if(delta > toucher->height || delta < -8*FRACUNIT) { // out of reach return; } sound = sfx_itemup; player = toucher->player; // Dead thing touching. // Can happen with a sliding player corpse. if(toucher->health <= 0) { return; } // Identify by sprite. switch(special->sprite) { // armor case SPR_ARM1: if(!P_GiveArmor(player, 1)) { return; } player->message = GOTARMOR; player->messagepic = 23; break; case SPR_ARM2: if(!P_GiveArmor(player, 2)) { return; } player->message = GOTMEGA; player->messagepic = 24; break; // bonus items case SPR_BON1: player->health+=2; // can go over 100% if(player->health > 200) { player->health = 200; } player->mo->health = player->health; player->message = GOTHTHBONUS; player->messagepic = 3; break; case SPR_BON2: player->armorpoints+=2; // can go over 100% if(player->armorpoints > 200) { player->armorpoints = 200; } if(!player->armortype) { player->armortype = 1; } player->message = GOTARMBONUS; player->messagepic = 4; break; case SPR_SOUL: player->health += 100; if(player->health > 200) { player->health = 200; } player->mo->health = player->health; player->message = GOTSUPER; player->messagepic = 5; sound = sfx_powerup; break; case SPR_MEGA: player->health = 200; player->mo->health = player->health; P_GiveArmor(player,2); player->message = GOTMSPHERE; player->messagepic = 6; sound = sfx_powerup; break; // cards // leave cards for everyone case SPR_BKEY: if(!(P_GiveCard(player, special, it_bluecard))) { return; } break; case SPR_YKEY: if(!(P_GiveCard(player, special, it_yellowcard))) { return; } break; case SPR_RKEY: if(!(P_GiveCard(player, special, it_redcard))) { return; } break; case SPR_BSKU: if(!(P_GiveCard(player, special, it_blueskull))) { return; } break; case SPR_YSKU: if(!(P_GiveCard(player, special, it_yellowskull))) { return; } break; case SPR_RSKU: if(!(P_GiveCard(player, special, it_redskull))) { return; } break; // medikits, heals case SPR_STIM: if(!P_GiveBody(player, 10)) { return; } player->message = GOTSTIM; player->messagepic = 31; break; case SPR_MEDI: if(!P_GiveBody(player, 25)) { return; } if(player->health < 25) { player->message = GOTMEDINEED; player->messagepic = 32; } else { player->message = GOTMEDIKIT; player->messagepic = 33; } break; // power ups case SPR_PINV: if(!P_GivePower(player, pw_invulnerability)) { return; } player->message = GOTINVUL; player->messagepic = 34; sound = sfx_powerup; break; case SPR_PSTR: if(!P_GivePower(player, pw_strength)) { return; } player->message = GOTBERSERK; player->messagepic = 35; if(player->readyweapon != wp_fist) { player->pendingweapon = wp_fist; } sound = sfx_powerup; break; case SPR_PINS: if(!P_GivePower(player, pw_invisibility)) { return; } player->message = GOTINVIS; player->messagepic = 36; sound = sfx_powerup; break; case SPR_SUIT: if(!P_GivePower(player, pw_ironfeet)) { return; } player->message = GOTSUIT; player->messagepic = 37; sound = sfx_powerup; break; case SPR_PMAP: if(!P_GivePower(player, pw_allmap)) { return; } player->message = GOTMAP; player->messagepic = 38; sound = sfx_powerup; break; case SPR_PVIS: if(!P_GivePower(player, pw_infrared)) { return; } player->message = GOTVISOR; player->messagepic = 39; sound = sfx_powerup; break; // ammo case SPR_CLIP: if(special->flags & MF_DROPPED) { if(!P_GiveAmmo(player,am_clip,0)) { return; } } else { if(!P_GiveAmmo(player,am_clip,1)) { return; } } player->message = GOTCLIP; player->messagepic = 7; break; case SPR_AMMO: if(!P_GiveAmmo(player, am_clip,5)) { return; } player->message = GOTCLIPBOX; player->messagepic = 8; break; case SPR_RCKT: if(!P_GiveAmmo(player, am_misl,1)) { return; } player->message = GOTROCKET; player->messagepic = 9; break; case SPR_BROK: if(!P_GiveAmmo(player, am_misl,5)) { return; } player->message = GOTROCKBOX; player->messagepic = 10; break; case SPR_CELL: if(!P_GiveAmmo(player, am_cell,1)) { return; } player->message = GOTCELL; player->messagepic = 11; break; case SPR_CELP: if(!P_GiveAmmo(player, am_cell,5)) { return; } player->message = GOTCELLBOX; player->messagepic = 12; break; case SPR_SHEL: if(!P_GiveAmmo(player, am_shell,1)) { return; } player->message = (gameskill == sk_baby)?GOTSHELLS2:GOTSHELLS; //villsa player->messagepic = 13; break; case SPR_SBOX: if(!P_GiveAmmo(player, am_shell,5)) { return; } player->message = GOTSHELLBOX; player->messagepic = 14; break; case SPR_BPAK: if(!player->backpack) { for(i = 0; i < NUMAMMO; i++) { player->maxammo[i] *= 2; } player->backpack = true; } for(i = 0; i < NUMAMMO; i++) { P_GiveAmmo(player, i, 1); } player->message = GOTBACKPACK; player->messagepic = 15; break; // weapons case SPR_BFUG: if(!P_GiveWeapon(player, special, wp_bfg, false)) { return; } player->message = GOTBFG9000; player->messagepic = 16; sound = sfx_sgcock; break; case SPR_MGUN: if(!P_GiveWeapon(player, special, wp_chaingun, special->flags&MF_DROPPED)) { return; } player->message = GOTCHAINGUN; player->messagepic = 17; sound = sfx_sgcock; break; case SPR_CSAW: if(!P_GiveWeapon(player, special, wp_chainsaw, false)) { return; } player->message = GOTCHAINSAW; player->messagepic = 18; sound = sfx_sgcock; break; case SPR_LAUN: if(!P_GiveWeapon(player, special, wp_missile, false)) { return; } player->message = GOTLAUNCHER; player->messagepic = 19; sound = sfx_sgcock; break; case SPR_PLSM: if(!P_GiveWeapon(player, special, wp_plasma, false)) { return; } player->message = GOTPLASMA; player->messagepic = 20; sound = sfx_sgcock; break; case SPR_SHOT: if(!P_GiveWeapon(player, special, wp_shotgun, special->flags&MF_DROPPED)) { return; } player->message = GOTSHOTGUN; player->messagepic = 21; sound = sfx_sgcock; break; case SPR_SGN2: if(!P_GiveWeapon(player, special, wp_supershotgun, special->flags&MF_DROPPED)) { return; } player->message = GOTSHOTGUN2; player->messagepic = 22; sound = sfx_sgcock; break; case SPR_LSRG: if(!P_GiveWeapon(player, special, wp_laser, false)) { return; } player->message = GOTLASER; sound = sfx_sgcock; break; case SPR_ART1: if(netgame && player->artifacts & (1<<ART_FAST)) { return; } player->artifacts |= (1<<ART_FAST); player->message = GOTARTIFACT1; player->messagepic = 41; break; case SPR_ART2: if(netgame && player->artifacts & (1<<ART_DOUBLE)) { return; } player->artifacts |= (1<<ART_DOUBLE); player->message = GOTARTIFACT2; player->messagepic = 42; break; case SPR_ART3: if(netgame && player->artifacts & (1<<ART_TRIPLE)) { return; } player->artifacts |= (1<<ART_TRIPLE); player->message = GOTARTIFACT3; player->messagepic = 43; break; default: if(special->type != MT_FAKEITEM) { CON_Printf(YELLOW, "P_SpecialThing: Unknown gettable thing: %s\n", sprnames[special->sprite]); special->flags &= ~MF_SPECIAL; return; } break; } if(special->flags & MF_TRIGTOUCH || special->type == MT_FAKEITEM) { if(special->tid) { P_QueueSpecial(special); } } if(special->type != MT_FAKEITEM) { if(special->flags & MF_COUNTITEM) { player->itemcount++; } if(special->flags & MF_COUNTSECRET) { player->secretcount++; } P_RemoveMobj(special); player->bonuscount += BONUSADD; if(player == &players[consoleplayer]) { S_StartSound(NULL, sound); } } }
// // P_UnArchiveThinkers // void P_UnArchiveThinkers (void) { byte tclass; thinker_t* currentthinker; thinker_t* next; mobj_t* mobj; // remove all the current thinkers currentthinker = thinkercap.next; while (currentthinker != &thinkercap) { next = currentthinker->next; if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) P_RemoveMobj ((mobj_t *)currentthinker); else Z_Free (currentthinker); currentthinker = next; } P_InitThinkers (); // read in saved thinkers while (1) { tclass = saveg_read8(); switch (tclass) { case tc_end: return; // end of list case tc_mobj: saveg_read_pad(); mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL); saveg_read_mobj_t(mobj); // haleyjd 09/29/10: Strife sets the targets of non-allied creatures // who had a non-NULL target at save time to players[0].mo so that // they won't fall back asleep. // // BUG: As the player may not have been spawned yet, we could be // setting monsters' targets to the mobj which was spawned by // P_SetupLevel and then removed just above. Due to a subtle glitch // in the DOOM engine whereby all things removed in this function // are leaked until the next time P_SetupLevel is called, this is a // safe operation - the call to P_InitThinkers above stops any of // the objects removed, including the player's previous body, from // being passed to Z_Free. One glitch relying on another! if(mobj->target != NULL && (mobj->flags & MF_ALLY) != MF_ALLY) mobj->target = players[0].mo; else mobj->target = NULL; // WARNING! Strife does not seem to set tracer! I am leaving it be // for now because so far no crashes have been observed, and failing // to set this here will almost certainly crash Choco. mobj->tracer = NULL; P_SetThingPosition (mobj); mobj->info = &mobjinfo[mobj->type]; // [STRIFE]: doesn't set these //mobj->floorz = mobj->subsector->sector->floorheight; //mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; P_AddThinker (&mobj->thinker); break; default: I_Error ("Unknown tclass %i in savegame",tclass); } } }
void P_UnArchiveThinkers (void) { thinker_t *th; mobj_t **mobj_p; // killough 2/14/98: Translation table size_t size; // killough 2/14/98: size of or index into table totallive = 0; // killough 3/26/98: Load boss brain state memcpy(&brain, save_p, sizeof brain); save_p += sizeof brain; // remove all the current thinkers for (th = thinkercap.next; th != &thinkercap; ) { thinker_t *next = th->next; if (th->function == P_MobjThinker) { P_RemoveMobj ((mobj_t *) th); P_RemoveThinkerDelayed(th); // fix mobj leak } else Z_Free (th); th = next; } P_InitThinkers (); // killough 2/14/98: count number of thinkers by skipping through them { byte *sp = save_p; // save pointer and skip header for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { // skip all entries, adding up count PADSAVEP(); /* cph 2006/07/30 - see comment below for change in layout of mobj_t */ save_p += sizeof(mobj_t)+3*sizeof(void*)-4*sizeof(fixed_t); } if (*--save_p != tc_end) I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p); // first table entry special: 0 maps to NULL *(mobj_p = malloc(size * sizeof *mobj_p)) = 0; // table of pointers save_p = sp; // restore save pointer } // read in saved thinkers for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 { mobj_t *mobj = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL); // killough 2/14/98 -- insert pointers to thinkers into table, in order: mobj_p[size] = mobj; PADSAVEP(); /* cph 2006/07/30 - * The end of mobj_t changed from * boolean invisible; * mobj_t* lastenemy; * mobj_t* above_monster; * mobj_t* below_monster; * void* touching_sectorlist; * to * mobj_t* lastenemy; * void* touching_sectorlist; * fixed_t PrevX, PrevY, PrevZ; * at prboom 2.4.4. There is code here to preserve the savegame format. * * touching_sectorlist is reconstructed anyway, so we now read in all * but the last 5 words from the savegame (filling all but the last 2 * fields of our current mobj_t. We then pull lastenemy from the 2nd of * the 5 leftover words, and skip the others. */ memcpy (mobj, save_p, sizeof(mobj_t)-2*sizeof(void*)-4*sizeof(fixed_t)); save_p += sizeof(mobj_t)-sizeof(void*)-4*sizeof(fixed_t); memcpy (&(mobj->lastenemy), save_p, sizeof(void*)); save_p += 4*sizeof(void*); mobj->state = states + (int) mobj->state; if (mobj->player) (mobj->player = &players[(int) mobj->player - 1]) -> mo = mobj; P_SetThingPosition (mobj); mobj->info = &mobjinfo[mobj->type]; // killough 2/28/98: // Fix for falling down into a wall after savegame loaded: // mobj->floorz = mobj->subsector->sector->floorheight; // mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function = P_MobjThinker; P_AddThinker (&mobj->thinker); if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL | MF_CORPSE))) totallive++; } // killough 2/14/98: adjust target and tracer fields, plus // lastenemy field, to correctly point to mobj thinkers. // NULL entries automatically handled by first table entry. // // killough 11/98: use P_SetNewTarget() to set fields for (th = thinkercap.next ; th != &thinkercap ; th=th->next) { P_SetNewTarget(&((mobj_t *) th)->target, mobj_p[P_GetMobj(((mobj_t *)th)->target,size)]); P_SetNewTarget(&((mobj_t *) th)->tracer, mobj_p[P_GetMobj(((mobj_t *)th)->tracer,size)]); P_SetNewTarget(&((mobj_t *) th)->lastenemy, mobj_p[P_GetMobj(((mobj_t *)th)->lastenemy,size)]); } { // killough 9/14/98: restore soundtargets int i; for (i = 0; i < numsectors; i++) { mobj_t *target; memcpy(&target, save_p, sizeof target); save_p += sizeof target; // Must verify soundtarget. See P_ArchiveThinkers. P_SetNewTarget(§ors[i].soundtarget, mobj_p[P_GetMobj(target,size)]); } } free(mobj_p); // free translation table // killough 3/26/98: Spawn icon landings: if (gamemode == commercial) P_SpawnBrainTargets(); }
void P_SetupLevel(int episode, int map, int playermask, skill_t skill) { int i; int parm; char lumpname[9]; int lumpnum; mobj_t *mobj; for (i = 0; i < MAXPLAYERS; i++) { players[i].killcount = players[i].secretcount = players[i].itemcount = 0; } players[consoleplayer].viewz = 1; // will be set by player think // Waiting-for-level-load song; not played if playing music from CD // (the seek time will be so long it will just make loading take // longer) if (!cdmusic) { S_StartSongName("chess", true); } Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1); P_InitThinkers(); leveltime = 0; sprintf(lumpname, "MAP%02d", map); lumpnum = W_GetNumForName(lumpname); // // Begin processing map lumps // Note: most of this ordering is important // P_LoadBlockMap(lumpnum + ML_BLOCKMAP); P_LoadVertexes(lumpnum + ML_VERTEXES); P_LoadSectors(lumpnum + ML_SECTORS); P_LoadSideDefs(lumpnum + ML_SIDEDEFS); P_LoadLineDefs(lumpnum + ML_LINEDEFS); P_LoadSubsectors(lumpnum + ML_SSECTORS); P_LoadNodes(lumpnum + ML_NODES); P_LoadSegs(lumpnum + ML_SEGS); rejectmatrix = W_CacheLumpNum(lumpnum + ML_REJECT, PU_LEVEL); P_GroupLines(); bodyqueslot = 0; po_NumPolyobjs = 0; deathmatch_p = deathmatchstarts; P_LoadThings(lumpnum + ML_THINGS); PO_Init(lumpnum + ML_THINGS); // Initialize the polyobjs P_LoadACScripts(lumpnum + ML_BEHAVIOR); // ACS object code // // End of map lump processing // // If deathmatch, randomly spawn the active players TimerGame = 0; if (deathmatch) { for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) { // must give a player spot before deathmatchspawn mobj = P_SpawnMobj(playerstarts[0][i].x << 16, playerstarts[0][i].y << 16, 0, MT_PLAYER_FIGHTER); players[i].mo = mobj; G_DeathMatchSpawnPlayer(i); P_RemoveMobj(mobj); } } //! // @arg <n> // @category net // @vanilla // // For multiplayer games: exit each level after n minutes. // parm = M_CheckParmWithArgs("-timer", 1); if (parm) { TimerGame = atoi(myargv[parm + 1]) * 35 * 60; } } // set up world state P_SpawnSpecials(); // build subsector connect matrix // P_ConnectSubsectors (); // Load colormap and set the fullbright flag i = P_GetMapFadeTable(gamemap); W_ReadLump(i, colormaps); if (i == W_GetNumForName("COLORMAP")) { LevelUseFullBright = true; } else { // Probably fog ... don't use fullbright sprites LevelUseFullBright = false; } // preload graphics if (precache) R_PrecacheLevel(); // Check if the level is a lightning level P_InitLightning(); S_StopAllSound(); SN_StopAllSequences(); S_StartSong(gamemap, true); //printf ("free memory: 0x%x\n", Z_FreeMemory()); }
void P_SetupLevel (int map, skill_t skill) { int i; static char lumpname[16]; int lumpnum; mobj_t *mobj; extern int cy; M_ClearRandom (); P_LoadingPlaque (); D_printf ("P_SetupLevel(%i,%i)\n",map,skill); totalkills = totalitems = totalsecret = 0; for (i=0 ; i<MAXPLAYERS ; i++) { players[i].killcount = players[i].secretcount = players[i].itemcount = 0; } Z_CheckHeap (mainzone); #ifndef MARS Z_CheckHeap (refzone); #endif Z_FreeTags (mainzone); /*PrintHex (1,1,Z_FreeMemory (mainzone)); */ P_InitThinkers (); /* */ /* look for a regular (development) map first */ /* */ lumpname[0] = 'M'; lumpname[1] = 'A'; lumpname[2] = 'P'; lumpname[3] = '0' + map/10; lumpname[4] = '0' + map%10; lumpname[5] = 0; lumpnum = W_GetNumForName (lumpname); /* note: most of this ordering is important */ P_LoadBlockMap (lumpnum+ML_BLOCKMAP); P_LoadVertexes (lumpnum+ML_VERTEXES); P_LoadSectors (lumpnum+ML_SECTORS); P_LoadSideDefs (lumpnum+ML_SIDEDEFS); P_LoadLineDefs (lumpnum+ML_LINEDEFS); P_LoadSubsectors (lumpnum+ML_SSECTORS); P_LoadNodes (lumpnum+ML_NODES); P_LoadSegs (lumpnum+ML_SEGS); #ifdef MARS rejectmatrix = (byte *)(wadfileptr+BIGLONG(lumpinfo[lumpnum+ML_REJECT].filepos)); #else rejectmatrix = W_CacheLumpNum (lumpnum+ML_REJECT,PU_LEVEL); #endif P_GroupLines (); deathmatch_p = deathmatchstarts; P_LoadThings (lumpnum+ML_THINGS); /* */ /* if deathmatch, randomly spawn the active players */ /* */ if (netgame == gt_deathmatch) { for (i=0 ; i<MAXPLAYERS ; i++) if (playeringame[i]) { /* must give a player spot before deathmatchspawn */ mobj = P_SpawnMobj (deathmatchstarts[0].x<<16 ,deathmatchstarts[0].y<<16,0, MT_PLAYER); players[i].mo = mobj; G_DeathMatchSpawnPlayer (i); P_RemoveMobj (mobj); } } /* set up world state */ P_SpawnSpecials (); ST_InitEveryLevel (); /*printf ("free memory: 0x%x\n", Z_FreeMemory(mainzone)); */ cy = 4; #ifdef JAGUAR { extern byte *debugscreen; D_memset (debugscreen,0,32*224); } #endif iquehead = iquetail = 0; gamepaused = false; }