<untitled> (Text)

Ревизии: current

text/plain
text/html
source
Old rev.:
// Author: cvet
#include "_macros.fos"
#include "entire.fos"
#include "MsgStr.h"

import void DropDrugEffects(Critter& cr) from "drugs";
import void DropPoison(Critter& cr) from "poison";
import void DropRadiation(Critter& cr) from "radiation";
import void PlayVideo(Critter& cr, string& videoName, bool canStop) from "media";

const uint16 HellMapPid=MAP_replication_hell;
const uint16[] ReplicatorsMapPids={MAP_replication1,MAP_replication2,MAP_replication3,MAP_replication4};
uint ReplicatorPos=0;

// Permanent death
#define PERMANENT_DEATH_DEADS      (50000)
bool IsPermanentDeathInit=false;
uint[] PermanentDeath;

bool IsPermanentDeath(uint id) // Export
{
    if(not IsPermanentDeathInit)
    {
        GetAnyData("PermanentDeath",PermanentDeath);
        IsPermanentDeathInit=true;
    }

    for(uint i=0,j=PermanentDeath.length();i<j;i++)
        if(PermanentDeath[i]==id) return true;
    return false;
}

void ClearPermanentDeath() // Export
{
    PermanentDeath.resize(0);
    SetAnyData("PermanentDeath",PermanentDeath);
}

void AddPermanentDeath(uint id)
{
    if(not IsPermanentDeathInit)
    {
        GetAnyData("PermanentDeath",PermanentDeath);
        IsPermanentDeathInit=true;
    }

    if(not IsPermanentDeath(id))
    {
        push_back(PermanentDeath,id);
        SetAnyData("PermanentDeath",PermanentDeath);
    }
}


Map@ GetStartReplicatorMap()
{
//  uint16 replMapPid=ReplicatorsMapPids[ReplicatorPos];
//  if(++ReplicatorPos>=ReplicatorsMapPids.length()) ReplicatorPos=0;
//  return ::GetMapByPid(replMapPid,0);
    return ::GetMapByPid(ReplicatorsMapPids[0],0);
}

Map@ GetNearReplicatorMap(Critter& cr)
{
    Map@ nearMap=null;
    int nearDist=0;
    for(uint i=0,j=ReplicatorsMapPids.length();i<j;i++)
    {
        Map@ map=::GetMapByPid(ReplicatorsMapPids[i],0);
        if(valid(map))
        {
            Location@ loc=map.GetLocation();
            int dx=int(cr.WorldX)-int(loc.WorldX);
            int dy=int(cr.WorldY)-int(loc.WorldY);
            int dist=int(sqrt(dx*dx+dy*dy));

            if(not valid(nearMap) || dist<nearDist)
            {
                @nearMap=map;
                nearDist=dist;
            }
        }
    }
    return nearMap;
}

void SetStartLocation(Critter& cr) // Export
{
    Map@ replicator=GetStartReplicatorMap();
    if(not valid(replicator)) return;

    // Hidden fog on default player position
    uint zoneX=cr.WorldX/__GlobalMapZoneLength;
    uint zoneY=cr.WorldY/__GlobalMapZoneLength;
    cr.SetFog(zoneX  ,zoneY  ,FOG_FULL);
    cr.SetFog(zoneX-1,zoneY-1,FOG_FULL);
    cr.SetFog(zoneX  ,zoneY-1,FOG_FULL);
    cr.SetFog(zoneX+1,zoneY-1,FOG_FULL);
    cr.SetFog(zoneX-1,zoneY  ,FOG_FULL);
    cr.SetFog(zoneX+1,zoneY  ,FOG_FULL);
    cr.SetFog(zoneX-1,zoneY+1,FOG_FULL);
    cr.SetFog(zoneX  ,zoneY+1,FOG_FULL);
    cr.SetFog(zoneX+1,zoneY+1,FOG_FULL);

    cr.TransitToMap(replicator.Id,ENTIRE_REPLICATION);

    cr.SetKnownLoc(true,replicator.GetLocation().Id);
    cr.SetKnownLoc(false,LOCATION_ReplicationHell);
    uint16 replPid=replicator.GetLocation().GetProtoId();
    if(replPid==LOCATION_Replication1)
    {
        cr.SetKnownLoc(false,LOCATION_Den);
        cr.SetKnownLoc(false,LOCATION_Klamath);
    }
    else if(replPid==LOCATION_Replication2)
    {
        cr.SetKnownLoc(false,LOCATION_Modoc);
    }
    else if(replPid==LOCATION_Replication3)
    {
        cr.SetKnownLoc(false,LOCATION_Redding);
    }
    else if(replPid==LOCATION_Replication4)
    {
        cr.SetKnownLoc(false,LOCATION_BrokenHills);
        cr.SetKnownLoc(false,LOCATION_NewReno);
    }

    zoneX=cr.WorldX/__GlobalMapZoneLength;
    zoneY=cr.WorldY/__GlobalMapZoneLength;
    cr.SetFog(zoneX  ,zoneY  ,FOG_NONE);
    cr.SetFog(zoneX-1,zoneY-1,FOG_SELF);
    cr.SetFog(zoneX  ,zoneY-1,FOG_SELF);
    cr.SetFog(zoneX+1,zoneY-1,FOG_SELF);
    cr.SetFog(zoneX-1,zoneY  ,FOG_SELF);
    cr.SetFog(zoneX+1,zoneY  ,FOG_SELF);
    cr.SetFog(zoneX-1,zoneY+1,FOG_SELF);
    cr.SetFog(zoneX  ,zoneY+1,FOG_SELF);
    cr.SetFog(zoneX+1,zoneY+1,FOG_SELF);
}

void SetReplicationTime(Critter& cr) // Export
{
    int replTime=cr.Stat[ST_REPLICATION_TIME];
    if(replTime<0) return; // No respawn
    if(replTime==0) // Take default values
    {
        if(cr.IsPlayer()) replTime=1; // 3 minutes
        else replTime=Random(5,10); // 90-120 minutes
    }
    replTime*=REAL_MINUTE(1);
    cr.TimeoutBase[TO_REPLICATION]=__FullMinute+replTime;
}

bool IsHellMap(int mapPid)
{
return mapPid==HellMapPid;
}

void ReplicateCritter(Critter& cr) // Export
{
    Map@ dieMap=cr.GetMap();
    Map@ map=null;
    uint16 hx=0,hy=0;

    if(cr.IsPlayer())
    {
        bool dieMapIsHell=(valid(dieMap) && IsHellMap(dieMap.GetProtoId()));

        if(cr.Stat[ST_REPLICATION_MONEY]<-999999999)
        {
            @map=GetMapByPid(HellMapPid,0);

            if(not dieMapIsHell)
            {
                GameVar@ hellVisits=GetLocalVar(LVAR_hell_visits,cr.Id);
                hellVisits+=1;

                // Show hell video
                if(hellVisits==1) PlayVideo(cr,"TheLifeAfterHell.avi",false);

                // Permanent death
                if(hellVisits>PERMANENT_DEATH_DEADS)
                {
                    AddPermanentDeath(cr.Id);
                    cr.SayMsg(SAY_NETMSG,TEXTMSG_GAME,STR_NET_PERMANENT_DEATH);
                    cr.Disconnect();
                }
            }
        }
        else
        {
            @map=GetNearReplicatorMap(cr);
        }

        if(not valid(map) || not GetEntireFreeHex(map,ENTIRE_REPLICATION,hx,hy))
        {
            // Continue dead
            cr.TimeoutBase[TO_REPLICATION]=__FullMinute+REAL_MINUTE(1);
            return;
        }

        if(_CritCanDropItemsOnDead(cr))
        {
            Map@ dropMap=cr.GetMap();
            Item@[] items;
            cr.GetItems(-1,items);
            // Disable drop of hidden items
            for(uint i=0,j=items.length();i<j;i++) if(FLAG(items[i].Flags,ITEM_HIDDEN)) @items[i]=null;
            if(valid(dropMap)) MoveItems(items,dropMap,cr.HexX,cr.HexY);
            else DeleteItems(items);
        }

        if(not dieMapIsHell)
        {
            cr.StatBase[ST_REPLICATION_MONEY]-=cr.Stat[ST_REPLICATION_COST];
            _CritAddItem(cr,PID_FLOWER,1);
            if(cr.Stat[ST_REPLICATION_MONEY]>=100) _CritAddItem(cr,PID_G_CAPS,1000); // Add radio
        }
        cr.StatBase[ST_REPLICATION_COUNT]++;
    }
    else
    {
        cr.DropPlanes();
        cr.ClearEnemyStackNpc();
        cr.StatBase[ST_LAST_WEAPON_ID]=0;
        @map=cr.GetMap();
        if(not valid(map)) // On global, delete
        {
            DeleteNpc(cr);
            return;
        }
        hx=cr.HexX;
        hy=cr.HexY;

        if(cr.Stat[ST_DEAD_BLOCKER_ID]!=0)
        {
            Item@ block=::GetItem(cr.Stat[ST_DEAD_BLOCKER_ID]);
            if(valid(block)) DeleteItem(block);
            cr.StatBase[ST_DEAD_BLOCKER_ID]=0;
        }

        if(not map.IsHexPassed(hx,hy))
        {
            bool founded=false;
            for(int x=-1;x<=1;x++)
            {
                for(int y=-1;y<=1;y++)
                {
                    if(x==0 && y==0) continue; // Skip direct position
                    if((hx%2)==1 && ((x==-1 && y==1) || (x==1 && y==1))) continue;
                    if((hx%2)==0 && ((x==-1 && y==-1) || (x==1 && y==-1))) continue;

                    if(map.IsHexPassed(hx+x,hy+y))
                    {
                        hx+=x;
                        hy+=y;
                        founded=true;
                        break;
                    }
                }
                if(founded) break;
            }

            if(not founded)
            {
                // Continue dead
                cr.TimeoutBase[TO_REPLICATION]=__FullMinute+REAL_MINUTE(1);
                return;
            }
        }
    }

    cr.TransitToMap(map.Id,hx,hy,Random(0,5));
    cr.DamageBase[DAMAGE_EYE]=0;
    cr.DamageBase[DAMAGE_RIGHT_ARM]=0;
    cr.DamageBase[DAMAGE_LEFT_ARM]=0;
    cr.DamageBase[DAMAGE_RIGHT_LEG]=0;
    cr.DamageBase[DAMAGE_LEFT_LEG]=0;
    cr.ToLife();
    cr.StatBase[ST_CURRENT_HP]=cr.Stat[ST_MAX_LIFE];
    cr.StatBase[ST_CURRENT_AP]=cr.Stat[ST_ACTION_POINTS]*100;
    DropPoison(cr);
    DropRadiation(cr);
    if(cr.IsNpc() || map.GetProtoId()!=HellMapPid) DropDrugEffects(cr); // Note: This function clear effects of all active drugs/radiation/poison!
    cr.DropTimers();
    for(uint i=TIMEOUT_BEGIN;i<=TIMEOUT_END;i++) if(i!=TO_KARMA_VOTING) cr.TimeoutBase[i]=0;
}

//
// Turret
//
void _TurretInit(Critter& turret, bool firstTime)
{
    turret.StatBase[ST_PERCEPTION]=10;
    turret.SkillBase[SK_BIG_GUNS]=300;
    turret.SkillBase[SK_ENERGY_WEAPONS]=300;
    turret.ModeBase[MODE_NO_ENEMY_STACK]=1;
    turret.ModeBase[MODE_UNLIMITED_AMMO]=1;
}

//
// Hubologist
//
void _HubologistInit(Critter& hubologist, bool firstTime)
{
    hubologist.ModeBase[MODE_NO_ENEMY_STACK]=1;
}

Комментарии:

Нет